createMessage now returns a promise.

Also, fix all broken tests, mostly related to this.
This commit is contained in:
JC Brand 2018-08-18 11:28:51 +02:00
parent b4110dc162
commit ca9229a906
11 changed files with 703 additions and 571 deletions

6
dist/converse.js vendored
View File

@ -63132,7 +63132,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
} else {
resolve(this.messages.create(attrs));
}
});
}).catch(e => reject(e));
});
},
@ -63323,7 +63323,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_
if (!message) {
// Only create the message when we're sure it's not a duplicate
chatbox.incrementUnreadMsgCounter(chatbox.createMessage(stanza, original_stanza));
chatbox.createMessage(stanza, original_stanza).then(msg => chatbox.incrementUnreadMsgCounter(msg)).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
}
@ -73120,7 +73120,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
return;
}
this.incrementUnreadMsgCounter(this.createMessage(stanza, original_stanza));
this.createMessage(stanza, original_stanza).then(msg => this.incrementUnreadMsgCounter(msg)).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
if (sender !== this.get('nick')) {

View File

@ -27,10 +27,11 @@
_converse.emit('rosterContactsFetched');
test_utils.openControlBox();
let view;
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
test_utils.waitUntil(() => _converse.chatboxes.length == 2).then(() => {
var view = _converse.chatboxviews.get(contact_jid);
test_utils.openChatBoxFor(_converse, contact_jid)
.then(() => {
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);
@ -39,13 +40,15 @@
expect(info_messages.pop().textContent).toBe('/me: Write in the third person');
expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
var msg = $msg({
const 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);
return test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
}).then(() => {
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
done();
});
@ -741,7 +744,7 @@
spyOn(_converse, 'log');
recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
return test_utils.openChatBoxFor(_converse, recipient_jid);
}).then(() => {
}).then((view) => {
var msg = $msg({
'from': _converse.bare_jid,
'id': (new Date()).getTime(),
@ -757,7 +760,8 @@
'type': 'chat'
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
// Check that the chatbox and its view now exist
var chatbox = _converse.chatboxes.get(recipient_jid);
var chatboxview = _converse.chatboxviews.get(recipient_jid);
@ -886,7 +890,7 @@
spyOn(_converse, 'log');
recipient_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
return test_utils.openChatBoxFor(_converse, recipient_jid);
}).then(() => {
}).then((view) => {
var msg = $msg({
'from': _converse.bare_jid,
'id': (new Date()).getTime(),
@ -902,7 +906,8 @@
'type': 'chat'
}).c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
// Check that the chatbox and its view now exist
var chatbox = _converse.chatboxes.get(recipient_jid);
var chatboxview = _converse.chatboxviews.get(recipient_jid);
@ -1041,17 +1046,18 @@
_converse.emit('rosterContactsFetched');
test_utils.openControlBox();
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
let view;
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse, 'emit');
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
var view = _converse.chatboxviews.get(sender_jid);
view = _converse.chatboxviews.get(sender_jid);
expect(view.el.querySelectorAll('.chat-event').length).toBe(0);
// Insert <composing> message, to also check that
// text messages are inserted correctly with
// temporary chat events in the chat contents.
var msg = $msg({
const msg = $msg({
'to': _converse.bare_jid,
'xmlns': 'jabber:client',
'from': sender_jid,
@ -1059,14 +1065,18 @@
.c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
.tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(view.el.querySelectorAll('.chat-state-notification').length).toBe(1);
msg = $msg({
const msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
id: (new Date()).getTime()
}).c('body').c('inactive', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => (view.model.messages.length > 1));
}).then(() => {
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
expect($(view.el).find('.chat-state-notification').length).toBe(0);
done();
@ -1178,12 +1188,15 @@
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msg);
expect(_converse.incrementMsgCounter).toHaveBeenCalled();
expect(_converse.clearMsgCounter).not.toHaveBeenCalled();
expect(_converse.msg_counter).toBe(1);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
_converse.windowSate = previous_state;
done();
return test_utils.waitUntil(() => _converse.api.chats.get().length)
.then(() => {
expect(_converse.incrementMsgCounter).toHaveBeenCalled();
expect(_converse.clearMsgCounter).not.toHaveBeenCalled();
expect(_converse.msg_counter).toBe(1);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
_converse.windowSate = previous_state;
done();
});
}));
it("is cleared when the window is focused",
@ -1237,7 +1250,8 @@
// initial state
expect(_converse.msg_counter).toBe(0);
var message = 'This message will always increment the message counter from zero',
let view;
const message = 'This message will always increment the message counter from zero',
sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msgFactory = function () {
return $msg({
@ -1254,24 +1268,29 @@
// leave converse-chat page
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
expect(_converse.msg_counter).toBe(1);
return test_utils.waitUntil(() => _converse.api.chats.get().length)
.then(() => {
expect(_converse.msg_counter).toBe(1);
// come back to converse-chat page
_converse.saveWindowState(null, 'focus');
var view = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(view.el)).toBeTruthy();
expect(_converse.msg_counter).toBe(0);
// come back to converse-chat page
_converse.saveWindowState(null, 'focus');
view = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(view.el)).toBeTruthy();
expect(_converse.msg_counter).toBe(0);
// close chatbox and leave converse-chat page again
view.close();
_converse.windowState = 'hidden';
// close chatbox and leave converse-chat page again
view.close();
_converse.windowState = 'hidden';
// check that msg_counter is incremented from zero again
_converse.chatboxes.onMessage(msgFactory());
view = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(view.el)).toBeTruthy();
expect(_converse.msg_counter).toBe(1);
done();
// check that msg_counter is incremented from zero again
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => _converse.api.chats.get().length)
}).then(() => {
view = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(view.el)).toBeTruthy();
expect(_converse.msg_counter).toBe(1);
done();
});
}));
});
@ -1288,13 +1307,17 @@
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
let view;
test_utils.openChatBoxFor(_converse, sender_jid)
.then((view) => {
.then((v) => {
view = v;
view.model.save('scrolled', true);
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(view.model.get('num_unread')).toBe(1);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is not incremented when the message is received and ChatBoxView is scrolled down",
@ -1323,15 +1346,18 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () {
let chatbox;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
};
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(chatbox.get('num_unread')).toBe(1);
done();
});
@ -1344,17 +1370,19 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () {
let chatbox;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
};
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(chatbox.get('num_unread')).toBe(1);
done();
});
@ -1368,20 +1396,23 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
let chatbox;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () {
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
};
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
const chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(0);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is not cleared when ChatBoxView was scrolled up and the windows become focused",
@ -1391,21 +1422,24 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
var msgFactory = function () {
let chatbox;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
};
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(1);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
});
@ -1419,28 +1453,29 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
let msg, chatbox, indicator_el, selector;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
.then(() => test_utils.openChatBoxFor(_converse, sender_jid))
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
var msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
_converse.chatboxes.onMessage(msg);
var selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator',
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('1');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread too');
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('2');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is updated when message is received and chatbox is minimized",
@ -1452,28 +1487,30 @@
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let chatbox, indicator_el, msg, selector;
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
.then(() => test_utils.openChatBoxFor(_converse, sender_jid))
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize();
var msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
_converse.chatboxes.onMessage(msg);
var selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator',
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
selector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('1');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread too');
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('2');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is cleared when chatbox is maximzied after receiving messages in minimized mode",
@ -1484,27 +1521,28 @@
test_utils.createContacts(_converse, 'current');
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let chatbox, view, select_msgs_indicator;
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
};
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
.then(() => test_utils.openChatBoxFor(_converse, sender_jid))
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
view = _converse.chatboxviews.get(sender_jid);
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
var selectMsgsIndicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
};
chatboxview.minimize();
select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
view.minimize();
_converse.chatboxes.onMessage(msgFactory());
expect(selectMsgsIndicator().text()).toBe('1');
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(select_msgs_indicator().text()).toBe('1');
_converse.chatboxes.onMessage(msgFactory());
expect(selectMsgsIndicator().text()).toBe('2');
chatboxview.maximize();
expect(selectMsgsIndicator().length).toBe(0);
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
expect(select_msgs_indicator().text()).toBe('2');
view.maximize();
expect(select_msgs_indicator().length).toBe(0);
done();
});
}));
@ -1518,27 +1556,27 @@
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let view, chatbox, select_msgs_indicator;
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
.then(() => test_utils.openChatBoxFor(_converse, sender_jid))
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid);
chatbox = _converse.chatboxes.get(sender_jid);
view = _converse.chatboxviews.get(sender_jid);
var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
};
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator',
selectMsgsIndicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
expect(selectMsgsIndicator().text()).toBe('1');
chatboxview.viewUnreadMessages();
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(select_msgs_indicator().text()).toBe('1');
view.viewUnreadMessages();
_converse.rosterview.render();
expect(selectMsgsIndicator().length).toBe(0);
expect(select_msgs_indicator().length).toBe(0);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is not cleared after user clicks on roster view when chatbox is already opened and scrolled up",
@ -1550,24 +1588,25 @@
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let select_msgs_indicator, view;
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500)
.then(() => test_utils.openChatBoxFor(_converse, sender_jid))
.then(() => {
var chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
view = _converse.chatboxviews.get(sender_jid);
var msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
};
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator',
selectMsgsIndicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
var msgsIndicatorSelector = 'a.open-chat:contains("' + chatbox.get('fullname') + '") .msgs-indicator';
select_msgs_indicator = () => $(_converse.rosterview.el).find(msgsIndicatorSelector);
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
expect(selectMsgsIndicator().text()).toBe('1');
test_utils.openChatBoxFor(_converse, sender_jid);
expect(selectMsgsIndicator().text()).toBe('1');
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(select_msgs_indicator().text()).toBe('1');
return test_utils.openChatBoxFor(_converse, sender_jid);
}).then(() => {
expect(select_msgs_indicator().text()).toBe('1');
done();
});
}));
@ -1584,20 +1623,21 @@
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let selectUnreadMsgCount;
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
};
const selectUnreadMsgCount = function () {
selectUnreadMsgCount = function () {
const minimizedChatBoxView = _converse.minimized_chats.get(sender_jid);
return minimizedChatBoxView.el.querySelector('.message-count');
};
const chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => chatbox.messages.length);
}).then(() => {
const chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize();
@ -1605,7 +1645,7 @@
expect(u.isVisible(unread_count)).toBeTruthy();
expect(unread_count.innerHTML).toBe('1');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("is incremented when message is received and windows is not focused",
@ -1617,27 +1657,27 @@
_converse.emit('rosterContactsFetched');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
let selectUnreadMsgCount;
test_utils.openChatBoxFor(_converse, sender_jid)
.then(() => {
const msgFactory = function () {
return test_utils.createChatMessage(_converse, sender_jid,
'This message will be received as unread, but eventually will be read');
};
const selectUnreadMsgCount = function () {
selectUnreadMsgCount = function () {
const minimizedChatBoxView = _converse.minimized_chats.get(sender_jid);
return minimizedChatBoxView.el.querySelector('.message-count');
};
const chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize();
const view = _converse.chatboxviews.get(sender_jid);
view.minimize();
_converse.chatboxes.onMessage(msgFactory());
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
const unread_count = selectUnreadMsgCount();
expect(u.isVisible(unread_count)).toBeTruthy();
expect(unread_count.innerHTML).toBe('1');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("will render Openstreetmap-URL from geo-URI",

View File

@ -612,10 +612,14 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'dummy').then(function () {
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var chat_content = view.el.querySelector('.chat-content');
var $chat_content = $(chat_content);
let view, chat_content, $chat_content;
const ONE_DAY_LATER = 86400000;
const baseTime = new Date();
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'dummy')
.then(() => {
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
chat_content = view.el.querySelector('.chat-content');
$chat_content = $(chat_content);
var indicator = chat_content.querySelector('.date-separator');
expect(indicator).not.toBe(null);
expect(indicator.getAttribute('class')).toEqual('message date-separator');
@ -625,11 +629,8 @@
expect(chat_content.querySelector('div.chat-info').textContent).toBe(
"dummy has entered the groupchat"
);
var baseTime = new Date();
jasmine.clock().install();
jasmine.clock().mockDate(baseTime);
var ONE_DAY_LATER = 86400000;
jasmine.clock().tick(ONE_DAY_LATER);
/* <presence to="dummy@localhost/_converse.js-29092160"
@ -694,7 +695,7 @@
jasmine.clock().tick(ONE_DAY_LATER);
var stanza = Strophe.xmlHtmlNode(
const stanza = Strophe.xmlHtmlNode(
'<message xmlns="jabber:client"' +
' to="dummy@localhost/_converse.js-290929789"' +
' type="groupchat"' +
@ -703,8 +704,15 @@
' <delay xmlns="urn:xmpp:delay" stamp="'+moment().format()+'" from="some1@localhost"/>'+
'</message>').firstChild;
_converse.connection._dataRecv(test_utils.createRequest(stanza));
presence = $pres({
jasmine.clock().uninstall();
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
jasmine.clock().install();
jasmine.clock().mockDate(baseTime);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
const presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
from: 'coven@chat.shakespeare.lit/newguy'
}).c('x', {xmlns: Strophe.NS.MUC_USER})
@ -715,7 +723,7 @@
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
let time = chat_content.querySelectorAll('time.separator-text');
const time = chat_content.querySelectorAll('time.separator-text');
expect(time.length).toEqual(4);
var $indicator = $chat_content.find('.date-separator:eq(3)');
@ -727,7 +735,7 @@
jasmine.clock().tick(ONE_DAY_LATER);
stanza = Strophe.xmlHtmlNode(
const stanza = Strophe.xmlHtmlNode(
'<message xmlns="jabber:client"' +
' to="dummy@localhost/_converse.js-290929789"' +
' type="groupchat"' +
@ -736,11 +744,18 @@
' <delay xmlns="urn:xmpp:delay" stamp="'+moment().format()+'" from="some1@localhost"/>'+
'</message>').firstChild;
_converse.connection._dataRecv(test_utils.createRequest(stanza));
jasmine.clock().uninstall();
return test_utils.waitUntil(() => view.model.messages.length > 1);
}).then(() => {
jasmine.clock().install();
jasmine.clock().mockDate(baseTime);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
jasmine.clock().tick(ONE_DAY_LATER);
// Test a user leaving a groupchat
presence = $pres({
const presence = $pres({
to: 'dummy@localhost/_converse.js-29092160',
type: 'unavailable',
from: 'coven@chat.shakespeare.lit/newguy'
@ -754,10 +769,10 @@
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
time = chat_content.querySelectorAll('time.separator-text');
const time = chat_content.querySelectorAll('time.separator-text');
expect(time.length).toEqual(6);
$indicator = $chat_content.find('.date-separator:eq(5)');
const $indicator = $chat_content.find('.date-separator:eq(5)');
expect($indicator.attr('class')).toEqual('message date-separator');
expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
@ -766,11 +781,9 @@
expect($chat_content.find('div.chat-info:last').html()).toBe(
'newguy has left the groupchat. '+
'"Disconnected: Replaced by new connection"');
jasmine.clock().uninstall();
done();
return;
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("shows its description in the chat heading",
@ -827,16 +840,16 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
let view;
test_utils.waitUntilDiscoConfirmed(_converse, 'localhost', [], ['vcard-temp'])
.then(function () {
return test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'))
}).then(function () {
.then(() => test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname')))
.then(() => {
test_utils.createContacts(_converse, 'current');
return test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
}).then(function () {
var view = _converse.chatboxviews.get('lounge@localhost');
}).then(() => {
view = _converse.chatboxviews.get('lounge@localhost');
if (!$(view.el).find('.chat-area').length) { view.renderChatArea(); }
var message = '/me is tired';
const message = '/me is tired';
var nick = mock.chatroom_names[0],
msg = $msg({
'from': 'lounge@localhost/'+nick,
@ -845,17 +858,21 @@
'type': 'groupchat'
}).c('body').t(message).tree();
view.model.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(_.includes($(view.el).find('.chat-msg__author').text(), '**Dyon van de Wege')).toBeTruthy();
expect($(view.el).find('.chat-msg__text').text()).toBe(' is tired');
message = '/me is as well';
msg = $msg({
const message = '/me is as well';
const msg = $msg({
from: 'lounge@localhost/Max Mustermann',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').t(message).tree();
view.model.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length > 1);
}).then(() => {
expect(_.includes($(view.el).find('.chat-msg__author:last').text(), '**Max Mustermann')).toBeTruthy();
expect($(view.el).find('.chat-msg__text:last').text()).toBe(' is as well');
done();
@ -1495,20 +1512,18 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
let view;
const text = 'This is a received message';
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
spyOn(_converse, 'emit');
var view = _converse.chatboxviews.get('lounge@localhost');
view = _converse.chatboxviews.get('lounge@localhost');
if (!$(view.el).find('.chat-area').length) { view.renderChatArea(); }
var nick = mock.chatroom_names[0];
view.model.occupants.create({
'nick': nick,
'muc_jid': `${view.model.get('jid')}/${nick}`
});
var text = 'This is a received message';
var message = $msg({
from: 'lounge@localhost/'+nick,
id: '1',
@ -1516,6 +1531,8 @@
type: 'groupchat'
}).c('body').t(text);
view.model.onMessage(message.nodeTree);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
var $chat_content = $(view.el).find('.chat-content');
expect($chat_content.find('.chat-msg').length).toBe(1);
expect($chat_content.find('.chat-msg__text').text()).toBe(text);
@ -1568,9 +1585,10 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
let view;
var message = 'This message is received while the chat area is scrolled up';
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
var view = _converse.chatboxviews.get('lounge@localhost');
view = _converse.chatboxviews.get('lounge@localhost');
spyOn(view, 'scrollDown').and.callThrough();
/* Create enough messages so that there's a
* scrollbar.
@ -1584,8 +1602,10 @@
id: (new Date()).getTime(),
}).c('body').t('Message: '+i).tree());
}
return test_utils.waitUntil(() => view.model.messages.length === 20);
}).then(() => {
// Give enough time for `markScrolled` to have been called
setTimeout(function () {
setTimeout(() => {
view.content.scrollTop = 0;
view.model.onMessage(
$msg({
@ -1595,12 +1615,15 @@
id: (new Date()).getTime(),
}).c('body').t(message).tree());
// Now check that the message appears inside the chatbox in the DOM
var $chat_content = $(view.el).find('.chat-content');
var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg__text').text();
expect(msg_txt).toEqual(message);
expect(view.content.scrollTop).toBe(0);
done();
test_utils.waitUntil(() => view.model.messages.length === 21)
.then(() => {
// Now check that the message appears inside the chatbox in the DOM
var $chat_content = $(view.el).find('.chat-content');
var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg__text').text();
expect(msg_txt).toEqual(message);
expect(view.content.scrollTop).toBe(0);
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}, 500);
});
}));
@ -3435,19 +3458,19 @@
var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(0);
var room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.openAndEnterChatRoom(
_converse, 'kitchen', 'conference.shakespeare.lit', 'fires').then(function () {
let view, nick;
const room_jid = 'kitchen@conference.shakespeare.lit';
const message = 'fires: Your attention is required';
test_utils.openAndEnterChatRoom(_converse, 'kitchen', 'conference.shakespeare.lit', 'fires')
.then(() => {
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(0);
var view = _converse.chatboxviews.get(room_jid);
view = _converse.chatboxviews.get(room_jid);
view.model.set({'minimized': true});
var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
var message = 'fires: Your attention is required';
var nick = mock.chatroom_names[0];
nick = mock.chatroom_names[0];
view.model.onMessage($msg({
from: room_jid+'/'+nick,
@ -3455,7 +3478,8 @@
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').t(message).tree());
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1);
expect(roomspanel.el.querySelector('.msgs-indicator').textContent).toBe('1');
@ -3466,17 +3490,16 @@
'to': 'dummy@localhost',
'type': 'groupchat'
}).c('body').t(message).tree());
return test_utils.waitUntil(() => view.model.messages.length > 1);
}).then(() => {
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1);
expect(roomspanel.el.querySelector('.msgs-indicator').textContent).toBe('2');
view.model.set({'minimized': false});
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(0);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
describe("A Chat Status Notification", function () {
@ -3488,11 +3511,11 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
test_utils.openAndEnterChatRoom(
_converse, 'coven', 'chat.shakespeare.lit', 'some1').then(function () {
var room_jid = 'coven@chat.shakespeare.lit';
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
let view;
const room_jid = 'coven@chat.shakespeare.lit';
test_utils.openAndEnterChatRoom(_converse, 'coven', 'chat.shakespeare.lit', 'some1')
.then(() => {
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var $chat_content = $(view.el).find('.chat-content');
expect($chat_content.find('div.chat-info:first').html()).toBe("some1 has entered the groupchat");
@ -3534,9 +3557,9 @@
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
// Check that the notification appears inside the chatbox in the DOM
var events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
@ -3548,91 +3571,63 @@
expect(notifications.length).toBe(1);
expect(notifications[0].textContent).toEqual('newguy is typing');
const timeout_functions = [];
spyOn(window, 'setTimeout').and.callFake(function (func, delay) {
timeout_functions.push(func);
});
// Check that it doesn't appear twice
msg = $msg({
const msg = $msg({
from: room_jid+'/newguy',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
events = view.el.querySelectorAll('.chat-event');
return test_utils.waitUntil(() => view.model.messages.length > 1);
}).then(() => {
const events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
const notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(1);
expect(notifications[0].textContent).toEqual('newguy is typing');
expect(timeout_functions.length).toBe(1);
// <composing> state for a different occupant
msg = $msg({
const msg = $msg({
from: room_jid+'/nomorenicks',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
events = view.el.querySelectorAll('.chat-event');
return test_utils.waitUntil(() => view.model.messages.length > 2);
}).then(() => {
const events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
const notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(2);
expect(notifications[0].textContent).toEqual('newguy is typing');
expect(notifications[1].textContent).toEqual('nomorenicks is typing');
expect(timeout_functions.length).toBe(2);
// Check that new messages appear under the chat state
// notifications
msg = $msg({
const msg = $msg({
from: 'lounge@localhost/some1',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').t('hello world').tree();
view.model.onMessage(msg);
var messages = view.el.querySelectorAll('.message');
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
const messages = view.el.querySelectorAll('.message');
expect(messages.length).toBe(7);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world');
// Test that the composing notifications get removed
// via timeout.
timeout_functions[0]();
events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(1);
expect(notifications[0].textContent).toEqual('nomorenicks is typing');
timeout_functions[1]();
events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(0);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
});
@ -3642,10 +3637,11 @@
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
function (done, _converse) {
let view, msg
const room_jid = 'coven@chat.shakespeare.lit';
test_utils.openChatRoom(_converse, "coven", 'chat.shakespeare.lit', 'some1')
.then(() => {
var room_jid = 'coven@chat.shakespeare.lit';
var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
var $chat_content = $(view.el).find('.chat-content');
/* <presence to="dummy@localhost/_converse.js-29092160"
@ -3700,13 +3696,15 @@
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
// <composing> state
var msg = $msg({
const msg = $msg({
from: room_jid+'/newguy',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
// Check that the notification appears inside the chatbox in the DOM
var events = view.el.querySelectorAll('.chat-event');
@ -3720,63 +3718,69 @@
expect(notifications[0].textContent).toEqual('newguy is typing');
// Check that it doesn't appear twice
msg = $msg({
const msg = $msg({
from: room_jid+'/newguy',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
return test_utils.waitUntil(() => view.model.messages.length > 1);
}).then(() => {
events = view.el.querySelectorAll('.chat-event');
const events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
const notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(1);
expect(notifications[0].textContent).toEqual('newguy is typing');
// <composing> state for a different occupant
msg = $msg({
const msg = $msg({
from: room_jid+'/nomorenicks',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
events = view.el.querySelectorAll('.chat-event');
return test_utils.waitUntil(() => view.model.messages.length > 2);
}).then(() => {
const events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
const notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(2);
expect(notifications[0].textContent).toEqual('newguy is typing');
expect(notifications[1].textContent).toEqual('nomorenicks is typing');
// <paused> state from occupant who typed first
msg = $msg({
const msg = $msg({
from: room_jid+'/newguy',
id: (new Date()).getTime(),
to: 'dummy@localhost',
type: 'groupchat'
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
view.model.onMessage(msg);
events = view.el.querySelectorAll('.chat-event');
return test_utils.waitUntil(() => view.model.messages.length > 3);
}).then(() => {
const events = view.el.querySelectorAll('.chat-event');
expect(events.length).toBe(3);
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
notifications = view.el.querySelectorAll('.chat-state-notification');
const notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(2);
expect(notifications[0].textContent).toEqual('nomorenicks is typing');
expect(notifications[1].textContent).toEqual('newguy has stopped typing');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
});
});

View File

@ -1,11 +1,12 @@
(function (root, factory) {
define(["jquery", "jasmine", "mock", "test-utils"], factory);
} (this, function ($, jasmine, mock, test_utils) {
var _ = converse.env._;
var $pres = converse.env.$pres;
var $msg = converse.env.$msg;
var $iq = converse.env.$iq;
var u = converse.env.utils;
const _ = converse.env._,
$pres = converse.env.$pres,
$msg = converse.env.$msg,
$iq = converse.env.$iq,
u = converse.env.utils,
Strophe = converse.env.Strophe;
describe("The Controlbox", function () {
@ -72,18 +73,18 @@
test_utils.createContacts(_converse, 'all').openControlBox();
_converse.emit('rosterContactsFetched');
let chatview;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, sender_jid);
return test_utils.waitUntil(() => _converse.chatboxes.length).then(() => {
const chatview = _converse.chatboxviews.get(sender_jid);
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({
const msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
@ -91,10 +92,13 @@
}).c('body').t('hello').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll(".msgs-indicator"));
}).then(() => {
spyOn(chatview.model, 'incrementUnreadMsgCounter').and.callThrough();
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
msg = $msg({
const msg = $msg({
from: sender_jid,
to: _converse.connection.jid,
type: 'chat',
@ -102,14 +106,15 @@
}).c('body').t('hello again').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
return test_utils.waitUntil(() => chatview.model.incrementUnreadMsgCounter.calls.count());
}).then(() => {
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();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}));
});

View File

@ -20,15 +20,27 @@
null, ['discoInitialized'], {},
function (done, _converse) {
test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand').then(function () {
var chatroomview = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
var stanza = Strophe.xmlHtmlNode(
let view, stanza;
test_utils.openAndEnterChatRoom(_converse, 'trek-radio', 'conference.lightwitch.org', 'jcbrand')
.then(() => {
view = _converse.chatboxviews.get('trek-radio@conference.lightwitch.org');
stanza = Strophe.xmlHtmlNode(
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452" type="groupchat" from="trek-radio@conference.lightwitch.org/comndrdukath#0805 (STO)">
<body>negan</body>
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
</message>`).firstElementChild;
_converse.connection._dataRecv(test_utils.createRequest(stanza));
return test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length)
}).then(() => {
// XXX: we wait here until the first message appears before
// sending the duplicate. If we don't do that, then the
// duplicate appears before the promise for `createMessage`
// has been resolved, which means that the `isDuplicate`
// check fails because the first message doesn't exist yet.
//
// Not sure whether such a race-condition might pose a problem
// in "real-world" situations.
stanza = Strophe.xmlHtmlNode(
`<message xmlns="jabber:client" to="jcbrand@lightwitch.org/converse.js-73057452">
<result xmlns="urn:xmpp:mam:2" queryid="82d9db27-6cf8-4787-8c2c-5a560263d823" id="45fbbf2a-1059-479d-9283-c8effaf05621">
@ -39,10 +51,14 @@
</forwarded>
</result>
</message>`).firstElementChild;
chatroomview.model.onMessage(stanza);
expect(chatroomview.content.querySelectorAll('.chat-msg').length).toBe(1);
spyOn(view.model, 'isDuplicate').and.callThrough();
view.model.onMessage(stanza);
return test_utils.waitUntil(() => view.model.isDuplicate.calls.count());
}).then(() => {
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}))
});

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
const _ = converse.env._;
const $msg = converse.env.$msg;
const u = converse.env.utils;
const Strophe = converse.env.Strophe;
describe("The Minimized Chats Widget", function () {
@ -43,7 +44,7 @@
expect(_converse.minimized_chats.keys().length).toBe(2);
expect(_.includes(_converse.minimized_chats.keys(), contact_jid)).toBeTruthy();
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("can be toggled to hide or show minimized chats",
@ -74,7 +75,7 @@
}).then(() => {
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("shows the number messages received to minimized chats",
@ -99,7 +100,7 @@
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@localhost';
test_utils.openChatBoxFor(_converse, contact_jid);
}
return test_utils.waitUntil(() => _converse.chatboxes.length == 4).then(() => {
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});
@ -111,9 +112,11 @@
}).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());
}
return test_utils.waitUntil(() => chatview.model.messages.length);
}).then(() => {
expect(u.isVisible(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((3).toString());
// Chat state notifications don't increment the unread messages counter
// <composing> state
_converse.chatboxes.onMessage($msg({
@ -122,7 +125,7 @@
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());
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((i).toString());
// <paused> state
_converse.chatboxes.onMessage($msg({
@ -131,7 +134,7 @@
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());
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((i).toString());
// <gone> state
_converse.chatboxes.onMessage($msg({
@ -140,7 +143,7 @@
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());
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((i).toString());
// <inactive> state
_converse.chatboxes.onMessage($msg({
@ -149,9 +152,9 @@
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());
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((i).toString());
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
it("shows the number messages received to minimized groupchats",
@ -159,7 +162,7 @@
null, ['rosterGroupsFetched'], {},
function (done, _converse) {
var room_jid = 'kitchen@conference.shakespeare.lit';
const room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.openAndEnterChatRoom(
_converse, 'kitchen', 'conference.shakespeare.lit', 'fires').then(function () {
var view = _converse.chatboxviews.get(room_jid);
@ -175,11 +178,12 @@
type: 'groupchat'
}).c('body').t(message).tree();
view.model.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('1');
return test_utils.waitUntil(() => view.model.messages.length);
}).then(() => {
expect(u.isVisible(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe('1');
done();
});
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL))
}));
});
}));

View File

@ -229,14 +229,16 @@
// have to mock stanza traffic.
}, function (done, _converse) {
let view, nick;
const room_jid = 'kitchen@conference.shakespeare.lit';
test_utils.waitUntil(() => !_.isUndefined(_converse.rooms_list_view), 500)
.then(() => test_utils.openAndEnterChatRoom(_converse, 'kitchen', 'conference.shakespeare.lit', 'romeo'))
.then(() => {
const room_jid = 'kitchen@conference.shakespeare.lit';
const view = _converse.chatboxviews.get(room_jid);
view = _converse.chatboxviews.get(room_jid);
view.model.set({'minimized': true});
const contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
const nick = mock.chatroom_names[0];
nick = mock.chatroom_names[0];
view.model.onMessage(
$msg({
from: room_jid+'/'+nick,
@ -260,9 +262,11 @@
type: 'groupchat'
}).c('body').t('romeo: Your attention is required').tree()
);
var indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
return test_utils.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".msgs-indicator"));
}).then(() => {
spyOn(view.model, 'incrementUnreadMsgCounter').and.callThrough();
const indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
expect(indicator_el.textContent).toBe('1');
view.model.onMessage(
$msg({
from: room_jid+'/'+nick,
@ -271,14 +275,16 @@
type: 'groupchat'
}).c('body').t('romeo: and another thing...').tree()
);
indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
return test_utils.waitUntil(() => view.model.incrementUnreadMsgCounter.calls.count());
}).then(() => {
let indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
expect(indicator_el.textContent).toBe('2');
// 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");
expect(_.isNull(indicator_el));
room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom");
const room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom");
expect(_.includes(room_el.classList, 'unread-msgs')).toBeFalsy();
done();
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));

View File

@ -497,8 +497,6 @@
stanza.getElementsByTagName(_converse.ACTIVE).length && _converse.ACTIVE ||
stanza.getElementsByTagName(_converse.GONE).length && _converse.GONE;
const attrs = {
'chat_state': chat_state,
'is_archived': !_.isNil(archive),
@ -552,7 +550,7 @@
} else {
resolve(this.messages.create(attrs));
}
});
}).catch(e => reject(e))
});
},
@ -729,8 +727,11 @@
if (chatbox && !chatbox.handleMessageCorrection(stanza)) {
const msgid = stanza.getAttribute('id'),
message = msgid && chatbox.messages.findWhere({msgid});
if (!message) { // Only create the message when we're sure it's not a duplicate
chatbox.incrementUnreadMsgCounter(chatbox.createMessage(stanza, original_stanza));
if (!message) {
// Only create the message when we're sure it's not a duplicate
chatbox.createMessage(stanza, original_stanza)
.then(msg => chatbox.incrementUnreadMsgCounter(msg))
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
}
_converse.emit('message', {'stanza': original_stanza, 'chatbox': chatbox});

View File

@ -128,6 +128,7 @@
//
// New functions which don't exist yet can also be added.
ChatBox: {
getMessageAttributesFromStanza (message, original_stanza) {
return new Promise((resolve, reject) => {
this.__super__.getMessageAttributesFromStanza.apply(this, arguments)

View File

@ -926,7 +926,9 @@
if (sender === '') {
return;
}
this.incrementUnreadMsgCounter(this.createMessage(stanza, original_stanza));
this.createMessage(stanza, original_stanza)
.then(msg => this.incrementUnreadMsgCounter(msg))
.catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
}
if (sender !== this.get('nick')) {
// We only emit an event if it's not our own message