Refactor out createMessage
.
Changes: * Avoids leaky abstraction of MUC code into converse-chatboxes * Avoid creating unnecessary message objects (e.g. without <body) * Add fix for #1369. * Rename spec/chatroom.js to spec/muc.js
This commit is contained in:
parent
3aaff4e973
commit
3c0e3d3fab
96
dist/converse.js
vendored
96
dist/converse.js
vendored
@ -51920,11 +51920,11 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__["default"].plugins
|
||||
'afterShown': _.noop
|
||||
});
|
||||
|
||||
function onHeadlineMessage(message) {
|
||||
async function onHeadlineMessage(message) {
|
||||
/* Handler method for all incoming messages of type "headline". */
|
||||
const from_jid = message.getAttribute('from');
|
||||
|
||||
if (utils.isHeadlineMessage(_converse, message)) {
|
||||
const from_jid = message.getAttribute('from');
|
||||
|
||||
if (_.includes(from_jid, '@') && !_converse.api.contacts.get(from_jid) && !_converse.allow_non_roster_messaging) {
|
||||
return;
|
||||
}
|
||||
@ -51942,19 +51942,21 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_1__["default"].plugins
|
||||
'from': from_jid
|
||||
});
|
||||
|
||||
chatbox.createMessage(message, message);
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
|
||||
await chatbox.messages.create(attrs);
|
||||
|
||||
_converse.emit('message', {
|
||||
'chatbox': chatbox,
|
||||
'stanza': message
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function registerHeadlineHandler() {
|
||||
_converse.connection.addHandler(onHeadlineMessage, null, 'message');
|
||||
_converse.connection.addHandler(message => {
|
||||
onHeadlineMessage(message);
|
||||
return true;
|
||||
}, null, 'message');
|
||||
}
|
||||
|
||||
_converse.on('connected', registerHeadlineHandler);
|
||||
@ -61803,8 +61805,10 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
'is_delayed': !_.isNil(delay),
|
||||
'is_spoiler': !_.isNil(spoiler),
|
||||
'message': _converse.chatboxes.getMessageBody(stanza) || undefined,
|
||||
'references': this.getReferencesFromStanza(stanza),
|
||||
'msgid': stanza.getAttribute('id'),
|
||||
'references': this.getReferencesFromStanza(stanza),
|
||||
'subject': _.propertyOf(stanza.querySelector('subject'))('textContent'),
|
||||
'thread': _.propertyOf(stanza.querySelector('thread'))('textContent'),
|
||||
'time': delay ? delay.getAttribute('stamp') : moment().format(),
|
||||
'type': stanza.getAttribute('type')
|
||||
};
|
||||
@ -61837,25 +61841,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
return attrs;
|
||||
},
|
||||
|
||||
async createMessage(message, original_stanza) {
|
||||
/* Create a Backbone.Message object inside this chat box
|
||||
* based on the identified message stanza.
|
||||
*/
|
||||
const attrs = await this.getMessageAttributesFromStanza(message, original_stanza),
|
||||
is_csn = u.isOnlyChatStateNotification(attrs);
|
||||
|
||||
if (is_csn && (attrs.is_delayed || attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == this.get('nick'))) {
|
||||
// XXX: MUC leakage
|
||||
// No need showing delayed or our own CSN messages
|
||||
return;
|
||||
} else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
|
||||
// TODO: handle <subject> messages (currently being done by ChatRoom)
|
||||
return;
|
||||
} else {
|
||||
return this.messages.create(attrs);
|
||||
}
|
||||
},
|
||||
|
||||
isHidden() {
|
||||
/* Returns a boolean to indicate whether a newly received
|
||||
* message will be visible to the user or not.
|
||||
@ -61952,7 +61937,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
});
|
||||
},
|
||||
|
||||
onErrorMessage(message) {
|
||||
async onErrorMessage(message) {
|
||||
/* Handler method for all incoming error message stanzas
|
||||
*/
|
||||
const from_jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
|
||||
@ -61990,8 +61975,8 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
_converse.log(message, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
|
||||
chatbox.createMessage(message, message);
|
||||
return true;
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
|
||||
chatbox.messages.create(attrs);
|
||||
},
|
||||
|
||||
getMessageBody(stanza) {
|
||||
@ -62023,7 +62008,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
_converse.api.send(receipt_stanza);
|
||||
},
|
||||
|
||||
onMessage(stanza) {
|
||||
async onMessage(stanza) {
|
||||
/* Handler method for all incoming single-user chat "message"
|
||||
* stanzas.
|
||||
*
|
||||
@ -62104,7 +62089,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
|
||||
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));
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(stanza, original_stanza);
|
||||
const msg = chatbox.messages.create(attrs);
|
||||
chatbox.incrementUnreadMsgCounter(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62112,8 +62099,6 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-cha
|
||||
'stanza': original_stanza,
|
||||
'chatbox': chatbox
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
getChatBox(jid, attrs = {}, create) {
|
||||
@ -65298,7 +65283,9 @@ _converse_core__WEBPACK_IMPORTED_MODULE_2__["default"].plugins.add('converse-mam
|
||||
|
||||
this.addSpinner();
|
||||
|
||||
_converse.api.archive.query(_.extend({
|
||||
_converse.api.archive.query( // TODO: only query from the last message we have
|
||||
// in our history
|
||||
_.extend({
|
||||
'groupchat': is_groupchat,
|
||||
'before': '',
|
||||
// Page backwards from the most recent message
|
||||
@ -66839,28 +66826,37 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
|
||||
return;
|
||||
}
|
||||
|
||||
const jid = stanza.getAttribute('from'),
|
||||
resource = Strophe.getResourceFromJid(jid),
|
||||
sender = resource && Strophe.unescapeNode(resource) || '';
|
||||
const attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza);
|
||||
|
||||
if (!attrs.nick) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.handleMessageCorrection(stanza)) {
|
||||
if (sender === '') {
|
||||
if (attrs.subject && !attrs.thread && !attrs.message) {
|
||||
// https://xmpp.org/extensions/xep-0045.html#subject-mod
|
||||
// -----------------------------------------------------
|
||||
// The subject is changed by sending a message of type "groupchat" to the <room@service>,
|
||||
// where the <message/> MUST contain a <subject/> element that specifies the new subject but
|
||||
// MUST NOT contain a <body/> element (or a <thread/> element).
|
||||
_utils_form__WEBPACK_IMPORTED_MODULE_7__["default"].safeSave(this, {
|
||||
'subject': {
|
||||
'author': attrs.nick,
|
||||
'text': attrs.subject || ''
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const subject_el = stanza.querySelector('subject');
|
||||
const is_csn = _utils_form__WEBPACK_IMPORTED_MODULE_7__["default"].isOnlyChatStateNotification(attrs),
|
||||
own_message = Strophe.getResourceFromJid(attrs.from) == this.get('nick');
|
||||
|
||||
if (subject_el) {
|
||||
const subject = _.propertyOf(subject_el)('textContent') || '';
|
||||
_utils_form__WEBPACK_IMPORTED_MODULE_7__["default"].safeSave(this, {
|
||||
'subject': {
|
||||
'author': sender,
|
||||
'text': subject
|
||||
}
|
||||
});
|
||||
if (is_csn && (attrs.is_delayed || own_message)) {
|
||||
// No need showing delayed or our own CSN messages
|
||||
return;
|
||||
}
|
||||
|
||||
const msg = await this.createMessage(stanza, original_stanza);
|
||||
const msg = await this.messages.create(attrs);
|
||||
|
||||
if (forwarded && msg && msg.get('sender') === 'me') {
|
||||
msg.save({
|
||||
@ -66871,7 +66867,7 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
|
||||
this.incrementUnreadMsgCounter(msg);
|
||||
}
|
||||
|
||||
if (sender !== this.get('nick')) {
|
||||
if (attrs.nick !== this.get('nick')) {
|
||||
// We only emit an event if it's not our own message
|
||||
_converse.emit('message', {
|
||||
'stanza': original_stanza,
|
||||
|
@ -62,114 +62,111 @@
|
||||
it("autocompletes when the user presses tab",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy')
|
||||
.then(() => {
|
||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||
expect(view.model.occupants.length).toBe(1);
|
||||
let presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/some1'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'some1@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
expect(view.model.occupants.length).toBe(2);
|
||||
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = "hello som";
|
||||
|
||||
// Press tab
|
||||
const tab_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 9
|
||||
}
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(1);
|
||||
expect(view.el.querySelector('.suggestion-box__results li').textContent).toBe('some1');
|
||||
|
||||
const backspace_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'keyCode': 8
|
||||
}
|
||||
for (var i=0; i<3; i++) {
|
||||
// Press backspace 3 times to remove "som"
|
||||
view.keyPressed(backspace_event);
|
||||
textarea.value = textarea.value.slice(0, textarea.value.length-1)
|
||||
view.keyUp(backspace_event);
|
||||
}
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeTruthy();
|
||||
|
||||
presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/some2'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'some2@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
|
||||
textarea.value = "hello s s";
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
|
||||
|
||||
const up_arrow_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': () => (up_arrow_event.defaultPrevented = true),
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 38
|
||||
}
|
||||
view.keyPressed(up_arrow_event);
|
||||
view.keyUp(up_arrow_event);
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
|
||||
expect(view.el.querySelector('.suggestion-box__results li[aria-selected="false"]').textContent).toBe('some1');
|
||||
expect(view.el.querySelector('.suggestion-box__results li[aria-selected="true"]').textContent).toBe('some2');
|
||||
|
||||
view.keyPressed({
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 13 // Enter
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||
const view = _converse.chatboxviews.get('lounge@localhost');
|
||||
expect(view.model.occupants.length).toBe(1);
|
||||
let presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/some1'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'some1@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
expect(textarea.value).toBe('hello s @some2 ');
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
expect(view.model.occupants.length).toBe(2);
|
||||
|
||||
// Test that pressing tab twice selects
|
||||
presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/z3r0'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'z3r0@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
textarea.value = "hello z";
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
const textarea = view.el.querySelector('textarea.chat-textarea');
|
||||
textarea.value = "hello som";
|
||||
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(textarea.value).toBe('hello @z3r0 ');
|
||||
// Press tab
|
||||
const tab_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 9
|
||||
}
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(1);
|
||||
expect(view.el.querySelector('.suggestion-box__results li').textContent).toBe('some1');
|
||||
|
||||
done();
|
||||
}).catch(_.partial(console.error, _));
|
||||
const backspace_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'keyCode': 8
|
||||
}
|
||||
for (var i=0; i<3; i++) {
|
||||
// Press backspace 3 times to remove "som"
|
||||
view.keyPressed(backspace_event);
|
||||
textarea.value = textarea.value.slice(0, textarea.value.length-1)
|
||||
view.keyUp(backspace_event);
|
||||
}
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeTruthy();
|
||||
|
||||
presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/some2'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'some2@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
|
||||
textarea.value = "hello s s";
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(view.el.querySelector('.suggestion-box__results').hidden).toBeFalsy();
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
|
||||
|
||||
const up_arrow_event = {
|
||||
'target': textarea,
|
||||
'preventDefault': () => (up_arrow_event.defaultPrevented = true),
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 38
|
||||
}
|
||||
view.keyPressed(up_arrow_event);
|
||||
view.keyUp(up_arrow_event);
|
||||
expect(view.el.querySelectorAll('.suggestion-box__results li').length).toBe(2);
|
||||
expect(view.el.querySelector('.suggestion-box__results li[aria-selected="false"]').textContent).toBe('some1');
|
||||
expect(view.el.querySelector('.suggestion-box__results li[aria-selected="true"]').textContent).toBe('some2');
|
||||
|
||||
view.keyPressed({
|
||||
'target': textarea,
|
||||
'preventDefault': _.noop,
|
||||
'stopPropagation': _.noop,
|
||||
'keyCode': 13 // Enter
|
||||
});
|
||||
expect(textarea.value).toBe('hello s @some2 ');
|
||||
|
||||
// Test that pressing tab twice selects
|
||||
presence = $pres({
|
||||
'to': 'dummy@localhost/resource',
|
||||
'from': 'lounge@localhost/z3r0'
|
||||
})
|
||||
.c('x', {xmlns: Strophe.NS.MUC_USER})
|
||||
.c('item', {
|
||||
'affiliation': 'none',
|
||||
'jid': 'z3r0@localhost/resource',
|
||||
'role': 'participant'
|
||||
});
|
||||
_converse.connection._dataRecv(test_utils.createRequest(presence));
|
||||
textarea.value = "hello z";
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
|
||||
view.keyPressed(tab_event);
|
||||
view.keyUp(tab_event);
|
||||
expect(textarea.value).toBe('hello @z3r0 ');
|
||||
done();
|
||||
}));
|
||||
});
|
||||
}));
|
||||
|
@ -44,7 +44,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t('hello world').tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
|
||||
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
|
||||
done();
|
||||
@ -71,7 +71,7 @@
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(1);
|
||||
@ -322,7 +322,7 @@
|
||||
done();
|
||||
}));
|
||||
|
||||
it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
|
||||
it("can be closed by clicking a DOM element with class 'close-chatbox-button'",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
async function (done, _converse) {
|
||||
@ -533,7 +533,7 @@
|
||||
it("does not open a new chatbox",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
@ -547,7 +547,7 @@
|
||||
'type': 'chat',
|
||||
'id': (new Date()).getTime()
|
||||
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
done();
|
||||
}));
|
||||
@ -660,21 +660,20 @@
|
||||
|
||||
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||
spyOn(_converse, 'emit');
|
||||
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
|
||||
// <composing> state
|
||||
var msg = $msg({
|
||||
let msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
var view = _converse.chatboxviews.get(sender_jid);
|
||||
expect(view).toBeDefined();
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
|
||||
// Check that the notification appears inside the chatbox in the DOM
|
||||
@ -689,8 +688,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
events = view.el.querySelectorAll('.chat-state-notification');
|
||||
expect(events.length).toBe(1);
|
||||
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
|
||||
@ -725,7 +723,7 @@
|
||||
'to': recipient_jid,
|
||||
'type': 'chat'
|
||||
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.model.messages.length);
|
||||
// Check that the chatbox and its view now exist
|
||||
var chatbox = _converse.chatboxes.get(recipient_jid);
|
||||
@ -818,7 +816,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
@ -856,7 +854,7 @@
|
||||
'to': recipient_jid,
|
||||
'type': 'chat'
|
||||
}).c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.model.messages.length);
|
||||
// Check that the chatbox and its view now exist
|
||||
var chatbox = _converse.chatboxes.get(recipient_jid);
|
||||
@ -998,7 +996,7 @@
|
||||
'type': 'chat'})
|
||||
.c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.model.messages.length);
|
||||
expect(view.el.querySelectorAll('.chat-state-notification').length).toBe(1);
|
||||
msg = $msg({
|
||||
@ -1007,7 +1005,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').c('inactive', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => (view.model.messages.length > 1));
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
expect(view.el.querySelectorAll('.chat-state-notification').length).toBe(0);
|
||||
@ -1034,7 +1032,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').c('gone', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1]);
|
||||
@ -1121,7 +1119,7 @@
|
||||
spyOn(_converse, 'incrementMsgCounter').and.callThrough();
|
||||
spyOn(_converse, 'clearMsgCounter').and.callThrough();
|
||||
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(_converse.incrementMsgCounter).toHaveBeenCalled();
|
||||
expect(_converse.clearMsgCounter).not.toHaveBeenCalled();
|
||||
@ -1149,7 +1147,7 @@
|
||||
it("is not incremented when the message is received and the window is focused",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
@ -1157,8 +1155,8 @@
|
||||
expect(_converse.msg_counter).toBe(0);
|
||||
spyOn(_converse, 'incrementMsgCounter').and.callThrough();
|
||||
_converse.saveWindowState(null, 'focus');
|
||||
var message = 'This message will not increment the message counter';
|
||||
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
|
||||
const message = 'This message will not increment the message counter';
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
|
||||
msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
@ -1166,7 +1164,7 @@
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.incrementMsgCounter).not.toHaveBeenCalled();
|
||||
expect(_converse.msg_counter).toBe(0);
|
||||
done();
|
||||
@ -1237,7 +1235,7 @@
|
||||
|
||||
const view = await test_utils.openChatBoxFor(_converse, sender_jid)
|
||||
view.model.save('scrolled', true);
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.model.messages.length);
|
||||
expect(view.model.get('num_unread')).toBe(1);
|
||||
done();
|
||||
@ -1256,7 +1254,7 @@
|
||||
|
||||
await test_utils.openChatBoxFor(_converse, sender_jid);
|
||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(chatbox.get('num_unread')).toBe(0);
|
||||
done();
|
||||
}));
|
||||
@ -1359,14 +1357,14 @@
|
||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||
chatbox.save('scrolled', true);
|
||||
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => chatbox.messages.length);
|
||||
const 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);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => chatbox.messages.length > 1);
|
||||
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
|
||||
expect(indicator_el.textContent).toBe('2');
|
||||
@ -1390,14 +1388,14 @@
|
||||
chatboxview.minimize();
|
||||
|
||||
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => chatbox.messages.length);
|
||||
const 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);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => chatbox.messages.length > 1);
|
||||
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
|
||||
expect(indicator_el.textContent).toBe('2');
|
||||
|
104
spec/messages.js
104
spec/messages.js
@ -310,7 +310,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("message")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
@ -325,7 +325,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("Older message")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
msg = $msg({'id': 'aeb215', 'to': _converse.bare_jid})
|
||||
@ -338,7 +338,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("Inbetween message").up()
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
msg = $msg({'id': 'aeb216', 'to': _converse.bare_jid})
|
||||
@ -351,7 +351,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("another inbetween message")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
msg = $msg({'id': 'aeb217', 'to': _converse.bare_jid})
|
||||
@ -364,7 +364,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("An earlier message on the next day")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
msg = $msg({'id': 'aeb218', 'to': _converse.bare_jid})
|
||||
@ -377,7 +377,7 @@
|
||||
'type': 'chat'})
|
||||
.c('body').t("newer message from the next day")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
// Insert <composing> message, to also check that
|
||||
@ -391,7 +391,7 @@
|
||||
'type': 'chat'})
|
||||
.c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
msg = $msg({
|
||||
@ -403,7 +403,7 @@
|
||||
.c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
|
||||
.c('body').t("latest message")
|
||||
.tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
@ -464,7 +464,7 @@
|
||||
it("is ignored if it's a malformed headline message",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
@ -481,7 +481,7 @@
|
||||
type: 'chat',
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t("This headline message will not be shown").tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
expect(_converse.log.calledWith(
|
||||
"onMessage: Ignoring incoming headline message from JID: localhost",
|
||||
Strophe.LogLevel.INFO
|
||||
@ -523,7 +523,7 @@
|
||||
'to': _converse.bare_jid+'/another-resource',
|
||||
'type': 'chat'
|
||||
}).c('body').t(msgtext).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length)
|
||||
const chatbox = _converse.chatboxes.get(sender_jid);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
@ -574,7 +574,7 @@
|
||||
'to': recipient_jid,
|
||||
'type': 'chat'
|
||||
}).c('body').t(msgtext).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
// Check that the chatbox and its view now exist
|
||||
const chatbox = _converse.chatboxes.get(recipient_jid);
|
||||
@ -598,25 +598,25 @@
|
||||
it("will be discarded if it's a malicious message meant to look like a carbon copy",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.openControlBox();
|
||||
/* <message from="mallory@evil.example" to="b@xmpp.example">
|
||||
* <received xmlns='urn:xmpp:carbons:2'>
|
||||
* <forwarded xmlns='urn:xmpp:forward:0'>
|
||||
* <message from="alice@xmpp.example" to="bob@xmpp.example/client1">
|
||||
* <body>Please come to Creepy Valley tonight, alone!</body>
|
||||
* </message>
|
||||
* </forwarded>
|
||||
* </received>
|
||||
* </message>
|
||||
*/
|
||||
* <received xmlns='urn:xmpp:carbons:2'>
|
||||
* <forwarded xmlns='urn:xmpp:forward:0'>
|
||||
* <message from="alice@xmpp.example" to="bob@xmpp.example/client1">
|
||||
* <body>Please come to Creepy Valley tonight, alone!</body>
|
||||
* </message>
|
||||
* </forwarded>
|
||||
* </received>
|
||||
* </message>
|
||||
*/
|
||||
spyOn(_converse, 'log');
|
||||
var msgtext = 'Please come to Creepy Valley tonight, alone!';
|
||||
var sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
var impersonated_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
var msg = $msg({
|
||||
const msgtext = 'Please come to Creepy Valley tonight, alone!';
|
||||
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const impersonated_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const msg = $msg({
|
||||
'from': sender_jid,
|
||||
'id': (new Date()).getTime(),
|
||||
'to': _converse.connection.jid,
|
||||
@ -630,10 +630,10 @@
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat'
|
||||
}).c('body').t(msgtext).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
|
||||
// Check that chatbox for impersonated user is not created.
|
||||
var chatbox = _converse.chatboxes.get(impersonated_jid);
|
||||
let chatbox = _converse.chatboxes.get(impersonated_jid);
|
||||
expect(chatbox).not.toBeDefined();
|
||||
|
||||
// Check that the chatbox for the malicous user is not created
|
||||
@ -673,7 +673,7 @@
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
|
||||
await test_utils.waitUntil(() => chatview.model.messages.length);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
@ -734,7 +734,7 @@
|
||||
}).c('body').t(message).up()
|
||||
.c('delay', { xmlns:'urn:xmpp:delay', from: 'localhost', stamp: one_day_ago.format() })
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
@ -766,7 +766,7 @@
|
||||
id: new Date().getTime()
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
@ -1196,7 +1196,7 @@
|
||||
it("received may emit a message delivery receipt",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
test_utils.createContacts(_converse, 'current', 1);
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const msg_id = u.getUniqueId();
|
||||
@ -1211,7 +1211,7 @@
|
||||
'id': msg_id,
|
||||
}).c('body').t('Message!').up()
|
||||
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
const receipt = sizzle(`received[xmlns="${Strophe.NS.RECEIPTS}"]`, sent_stanzas[0].tree()).pop();
|
||||
expect(Strophe.serialize(receipt)).toBe(`<received id="${msg_id}" xmlns="${Strophe.NS.RECEIPTS}"/>`);
|
||||
done();
|
||||
@ -1241,7 +1241,7 @@
|
||||
'id': msg_id
|
||||
}).c('body').t('Message!').up()
|
||||
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
expect(_converse.chatboxes.sendReceiptStanza).not.toHaveBeenCalled();
|
||||
done();
|
||||
@ -1270,7 +1270,7 @@
|
||||
'id': msg_id
|
||||
}).c('body').t('Message!').up()
|
||||
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
expect(_converse.chatboxes.sendReceiptStanza).not.toHaveBeenCalled();
|
||||
done();
|
||||
@ -1475,7 +1475,7 @@
|
||||
// We don't already have an open chatbox for this user
|
||||
expect(_converse.chatboxes.get(sender_jid)).not.toBeDefined();
|
||||
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
|
||||
@ -1527,7 +1527,7 @@
|
||||
let chatbox = _converse.chatboxes.get(sender_jid);
|
||||
expect(chatbox).not.toBeDefined();
|
||||
// onMessage is a handler for received XMPP messages
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length)
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
@ -1536,7 +1536,7 @@
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
// onMessage is a handler for received XMPP messages
|
||||
_converse.allow_non_roster_messaging =true;
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.model.messages.length);
|
||||
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
|
||||
// Check that the chatbox and its view now exist
|
||||
@ -1824,7 +1824,7 @@
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t("This message will not be shown").up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.api.chats.get().length);
|
||||
expect(_converse.log).toHaveBeenCalledWith(
|
||||
"onMessage: Ignoring incoming message intended for a different resource: dummy@localhost/some-other-resource",
|
||||
@ -1840,7 +1840,7 @@
|
||||
id: '134234623462346'
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg);
|
||||
await _converse.chatboxes.onMessage(msg);
|
||||
await test_utils.waitUntil(() => _converse.chatboxviews.keys().length > 1, 1000);
|
||||
const view = _converse.chatboxviews.get(sender_jid);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
@ -2043,9 +2043,9 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect($(view.el).find('.chat-msg').hasClass('mentioned')).toBeTruthy();
|
||||
expect(u.hasClass('mentioned', view.el.querySelector('.chat-msg'))).toBeTruthy();
|
||||
done();
|
||||
}));
|
||||
|
||||
@ -2064,8 +2064,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('I wrote this message!').tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
expect(view.model.messages.last().get('sender')).toBe('me');
|
||||
done();
|
||||
}));
|
||||
@ -2091,7 +2090,7 @@
|
||||
}).tree();
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
const msg_id = u.getUniqueId();
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
'from': 'lounge@localhost/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'groupchat',
|
||||
@ -2102,10 +2101,10 @@
|
||||
expect(view.el.querySelector('.chat-msg__text').textContent)
|
||||
.toBe('But soft, what light through yonder airlock breaks?');
|
||||
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
'from': 'lounge@localhost/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder chimney breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
@ -2114,10 +2113,10 @@
|
||||
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
|
||||
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
'from': 'lounge@localhost/newguy',
|
||||
'to': _converse.connection.jid,
|
||||
'type': 'chat',
|
||||
'type': 'groupchat',
|
||||
'id': u.getUniqueId(),
|
||||
}).c('body').t('But soft, what light through yonder window breaks?').up()
|
||||
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
|
||||
@ -2207,7 +2206,7 @@
|
||||
expect(u.hasClass('correcting', view.el.querySelector('.chat-msg'))).toBe(false);
|
||||
|
||||
// Check that messages from other users are skipped
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
'from': room_jid+'/someone-else',
|
||||
'id': (new Date()).getTime(),
|
||||
'to': 'dummy@localhost',
|
||||
@ -2264,8 +2263,7 @@
|
||||
'to': 'dummy@localhost',
|
||||
'type': 'groupchat',
|
||||
}).c('body').t(body).up().tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.model.messages.once('rendered', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(1);
|
||||
done();
|
||||
}));
|
||||
@ -2302,7 +2300,7 @@
|
||||
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'6', 'end':'10', 'type':'mention', 'uri':'xmpp:z3r0@localhost'}).up()
|
||||
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'11', 'end':'14', 'type':'mention', 'uri':'xmpp:dummy@localhost'}).up()
|
||||
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'15', 'end':'23', 'type':'mention', 'uri':'xmpp:mr.robot@localhost'}).nodeTree;
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(view.el.querySelectorAll('.chat-msg__text').length).toBe(1);
|
||||
expect(view.el.querySelector('.chat-msg__text').outerHTML).toBe(
|
||||
|
@ -411,7 +411,7 @@
|
||||
'type': 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
view.el.querySelector('.chat-msg__text a').click();
|
||||
await test_utils.waitUntil(() => _converse.chatboxes.length === 3)
|
||||
@ -933,7 +933,7 @@
|
||||
'type': 'groupchat'
|
||||
}).c('body').t('Some message').tree();
|
||||
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
let stanza = Strophe.xmlHtmlNode(
|
||||
@ -1151,7 +1151,7 @@
|
||||
'to': 'dummy@localhost',
|
||||
'type': 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => 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).toBe('is tired');
|
||||
@ -1163,7 +1163,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(_.includes(sizzle('.chat-msg__author:last', view.el).pop().textContent, '**Max Mustermann')).toBeTruthy();
|
||||
expect(sizzle('.chat-msg__text:last', view.el).pop().textContent).toBe('is as well');
|
||||
@ -1836,7 +1836,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(text);
|
||||
view.model.onMessage(message.nodeTree);
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
expect(chat_content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
@ -1878,7 +1878,7 @@
|
||||
type: 'groupchat',
|
||||
id: view.model.messages.at(0).get('msgid')
|
||||
}).c('body').t(text);
|
||||
view.model.onMessage(message.nodeTree);
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
expect(chat_content.querySelectorAll('.chat-msg').length).toBe(1);
|
||||
expect(sizzle('.chat-msg__text:last').pop().textContent).toBe(text);
|
||||
expect(view.model.messages.length).toBe(1);
|
||||
@ -1912,7 +1912,7 @@
|
||||
// Give enough time for `markScrolled` to have been called
|
||||
setTimeout(async () => {
|
||||
view.content.scrollTop = 0;
|
||||
view.model.onMessage(
|
||||
await view.model.onMessage(
|
||||
$msg({
|
||||
from: 'lounge@localhost/someone',
|
||||
to: 'dummy@localhost.com',
|
||||
@ -1945,6 +1945,7 @@
|
||||
'</message>').firstChild;
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
const view = _converse.chatboxviews.get('jdev@conference.jabber.org');
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
const chat_content = view.el.querySelector('.chat-content');
|
||||
expect(sizzle('.chat-event:last').pop().textContent).toBe('Topic set by ralphm');
|
||||
expect(sizzle('.chat-topic:last').pop().textContent).toBe(text);
|
||||
@ -3999,7 +4000,7 @@
|
||||
var contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const nick = mock.chatroom_names[0];
|
||||
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
from: room_jid+'/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
to: 'dummy@localhost',
|
||||
@ -4010,7 +4011,7 @@
|
||||
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1);
|
||||
expect(roomspanel.el.querySelector('.msgs-indicator').textContent).toBe('1');
|
||||
|
||||
view.model.onMessage($msg({
|
||||
await view.model.onMessage($msg({
|
||||
'from': room_jid+'/'+nick,
|
||||
'id': (new Date()).getTime(),
|
||||
'to': 'dummy@localhost',
|
||||
@ -4076,14 +4077,14 @@
|
||||
// See XEP-0085 http://xmpp.org/extensions/xep-0085.html#definitions
|
||||
|
||||
// <composing> state
|
||||
var msg = $msg({
|
||||
let 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);
|
||||
await view.model.onMessage(msg);
|
||||
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length);
|
||||
|
||||
// Check that the notification appears inside the chatbox in the DOM
|
||||
@ -4109,8 +4110,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
|
||||
events = view.el.querySelectorAll('.chat-event');
|
||||
expect(events.length).toBe(3);
|
||||
@ -4131,8 +4131,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
events = view.el.querySelectorAll('.chat-event');
|
||||
expect(events.length).toBe(3);
|
||||
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
|
||||
@ -4153,7 +4152,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t('hello world').tree();
|
||||
view.model.onMessage(msg);
|
||||
await view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
|
||||
const messages = view.el.querySelectorAll('.message');
|
||||
@ -4259,8 +4258,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
|
||||
// Check that the notification appears inside the chatbox in the DOM
|
||||
var events = view.el.querySelectorAll('.chat-event');
|
||||
@ -4280,8 +4278,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
|
||||
events = view.el.querySelectorAll('.chat-event');
|
||||
expect(events.length).toBe(3);
|
||||
@ -4300,8 +4297,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
events = view.el.querySelectorAll('.chat-event');
|
||||
expect(events.length).toBe(3);
|
||||
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
|
||||
@ -4320,8 +4316,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
||||
view.model.onMessage(msg);
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
await view.model.onMessage(msg);
|
||||
events = view.el.querySelectorAll('.chat-event');
|
||||
expect(events.length).toBe(3);
|
||||
expect(events[0].textContent).toEqual('some1 has entered the groupchat');
|
@ -16,16 +16,17 @@
|
||||
it("is shown when a new private message is received",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
// TODO: not yet testing show_desktop_notifications setting
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.createContacts(_converse, 'current');
|
||||
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
||||
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
||||
spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
|
||||
|
||||
var message = 'This message will show a desktop notification';
|
||||
var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
|
||||
|
||||
const message = 'This message will show a desktop notification';
|
||||
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
|
||||
msg = $msg({
|
||||
from: sender_jid,
|
||||
to: _converse.connection.jid,
|
||||
@ -33,60 +34,63 @@
|
||||
id: (new Date()).getTime()
|
||||
}).c('body').t(message).up()
|
||||
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
||||
_converse.chatboxes.onMessage(msg); // This will emit 'message'
|
||||
await _converse.chatboxes.onMessage(msg); // This will emit 'message'
|
||||
await test_utils.waitUntil(() => _converse.api.chatviews.get(sender_jid));
|
||||
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
||||
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is shown when you are mentioned in a chat room",
|
||||
it("is shown when you are mentioned in a groupchat",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
test_utils.createContacts(_converse, 'current');
|
||||
test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function () {
|
||||
var view = _converse.chatboxviews.get('lounge@localhost');
|
||||
if (!$(view.el).find('.chat-area').length) { view.renderChatArea(); }
|
||||
var no_notification = false;
|
||||
if (typeof window.Notification === 'undefined') {
|
||||
no_notification = true;
|
||||
window.Notification = function () {
|
||||
return {
|
||||
'close': function () {}
|
||||
};
|
||||
await test_utils.createContacts(_converse, 'current');
|
||||
await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
|
||||
const view = _converse.api.chatviews.get('lounge@localhost');
|
||||
if (!view.el.querySelectorAll('.chat-area').length) {
|
||||
view.renderChatArea();
|
||||
}
|
||||
let no_notification = false;
|
||||
if (typeof window.Notification === 'undefined') {
|
||||
no_notification = true;
|
||||
window.Notification = function () {
|
||||
return {
|
||||
'close': function () {}
|
||||
};
|
||||
}
|
||||
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
||||
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
||||
|
||||
var message = 'dummy: This message will show a desktop notification';
|
||||
var nick = mock.chatroom_names[0],
|
||||
msg = $msg({
|
||||
from: 'lounge@localhost/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
_converse.chatboxes.onMessage(msg); // This will emit 'message'
|
||||
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
||||
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
||||
if (no_notification) {
|
||||
delete window.Notification;
|
||||
}
|
||||
done();
|
||||
}).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
|
||||
};
|
||||
}
|
||||
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
||||
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
||||
|
||||
const message = 'dummy: This message will show a desktop notification';
|
||||
const nick = mock.chatroom_names[0],
|
||||
msg = $msg({
|
||||
from: 'lounge@localhost/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(message).tree();
|
||||
await _converse.chatboxes.onMessage(msg); // This will emit 'message'
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
||||
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
||||
if (no_notification) {
|
||||
delete window.Notification;
|
||||
}
|
||||
done();
|
||||
}));
|
||||
|
||||
it("is shown for headline messages",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
function (done, _converse) {
|
||||
async function (done, _converse) {
|
||||
|
||||
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
||||
spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
|
||||
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
||||
var stanza = $msg({
|
||||
const stanza = $msg({
|
||||
'type': 'headline',
|
||||
'from': 'notify.example.com',
|
||||
'to': 'dummy@localhost',
|
||||
@ -97,6 +101,9 @@
|
||||
.c('x', {'xmlns': 'jabber:x:oob'})
|
||||
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
|
||||
_converse.connection._dataRecv(test_utils.createRequest(stanza));
|
||||
await test_utils.waitUntil(() => _converse.chatboxviews.keys().length);
|
||||
const view = _converse.chatboxviews.get('notify.example.com');
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
expect(
|
||||
_.includes(_converse.chatboxviews.keys(),
|
||||
'notify.example.com')
|
||||
@ -156,7 +163,7 @@
|
||||
describe("When play_sounds is set to true", function () {
|
||||
describe("A notification sound", function () {
|
||||
|
||||
it("is played when the current user is mentioned in a chat room",
|
||||
it("is played when the current user is mentioned in a groupchat",
|
||||
mock.initConverseWithPromises(
|
||||
null, ['rosterGroupsFetched'], {},
|
||||
async function (done, _converse) {
|
||||
@ -176,8 +183,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(text);
|
||||
view.model.onMessage(message.nodeTree);
|
||||
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
await test_utils.waitUntil(() => _converse.playSoundNotification.calls.count());
|
||||
expect(_converse.playSoundNotification).toHaveBeenCalled();
|
||||
|
||||
@ -188,7 +194,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(text);
|
||||
view.model.onMessage(message.nodeTree);
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
expect(_converse.playSoundNotification, 1);
|
||||
_converse.play_sounds = false;
|
||||
|
||||
@ -199,7 +205,7 @@
|
||||
to: 'dummy@localhost',
|
||||
type: 'groupchat'
|
||||
}).c('body').t(text);
|
||||
view.model.onMessage(message.nodeTree);
|
||||
await view.model.onMessage(message.nodeTree);
|
||||
expect(_converse.playSoundNotification, 1);
|
||||
_converse.play_sounds = false;
|
||||
done();
|
||||
|
@ -285,7 +285,7 @@
|
||||
view.model.set({'minimized': true});
|
||||
const contact_jid = mock.cur_names[5].replace(/ /g,'.').toLowerCase() + '@localhost';
|
||||
const nick = mock.chatroom_names[0];
|
||||
view.model.onMessage(
|
||||
await view.model.onMessage(
|
||||
$msg({
|
||||
from: room_jid+'/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
@ -293,13 +293,12 @@
|
||||
type: 'groupchat'
|
||||
}).c('body').t('foo').tree());
|
||||
|
||||
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
|
||||
// If the user isn't mentioned, the counter doesn't get incremented, but the text of the groupchat is bold
|
||||
let room_el = _converse.rooms_list_view.el.querySelector(".available-chatroom");
|
||||
expect(_.includes(room_el.classList, 'unread-msgs')).toBeTruthy();
|
||||
|
||||
// If the user is mentioned, the counter also gets updated
|
||||
view.model.onMessage(
|
||||
await view.model.onMessage(
|
||||
$msg({
|
||||
from: room_jid+'/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
@ -311,7 +310,7 @@
|
||||
spyOn(view.model, 'incrementUnreadMsgCounter').and.callThrough();
|
||||
let indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
|
||||
expect(indicator_el.textContent).toBe('1');
|
||||
view.model.onMessage(
|
||||
await view.model.onMessage(
|
||||
$msg({
|
||||
from: room_jid+'/'+nick,
|
||||
id: (new Date()).getTime(),
|
||||
|
@ -105,10 +105,10 @@ converse.plugins.add('converse-headline', {
|
||||
'afterShown': _.noop
|
||||
});
|
||||
|
||||
function onHeadlineMessage (message) {
|
||||
async function onHeadlineMessage (message) {
|
||||
/* Handler method for all incoming messages of type "headline". */
|
||||
const from_jid = message.getAttribute('from');
|
||||
if (utils.isHeadlineMessage(_converse, message)) {
|
||||
const from_jid = message.getAttribute('from');
|
||||
if (_.includes(from_jid, '@') &&
|
||||
!_converse.api.contacts.get(from_jid) &&
|
||||
!_converse.allow_non_roster_messaging) {
|
||||
@ -125,14 +125,17 @@ converse.plugins.add('converse-headline', {
|
||||
'type': _converse.HEADLINES_TYPE,
|
||||
'from': from_jid
|
||||
});
|
||||
chatbox.createMessage(message, message);
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
|
||||
await chatbox.messages.create(attrs);
|
||||
_converse.emit('message', {'chatbox': chatbox, 'stanza': message});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function registerHeadlineHandler () {
|
||||
_converse.connection.addHandler(onHeadlineMessage, null, 'message');
|
||||
_converse.connection.addHandler(message => {
|
||||
onHeadlineMessage(message);
|
||||
return true
|
||||
}, null, 'message');
|
||||
}
|
||||
_converse.on('connected', registerHeadlineHandler);
|
||||
_converse.on('reconnected', registerHeadlineHandler);
|
||||
|
@ -544,8 +544,10 @@ converse.plugins.add('converse-chatboxes', {
|
||||
'is_delayed': !_.isNil(delay),
|
||||
'is_spoiler': !_.isNil(spoiler),
|
||||
'message': _converse.chatboxes.getMessageBody(stanza) || undefined,
|
||||
'references': this.getReferencesFromStanza(stanza),
|
||||
'msgid': stanza.getAttribute('id'),
|
||||
'references': this.getReferencesFromStanza(stanza),
|
||||
'subject': _.propertyOf(stanza.querySelector('subject'))('textContent'),
|
||||
'thread': _.propertyOf(stanza.querySelector('thread'))('textContent'),
|
||||
'time': delay ? delay.getAttribute('stamp') : moment().format(),
|
||||
'type': stanza.getAttribute('type')
|
||||
};
|
||||
@ -573,25 +575,6 @@ converse.plugins.add('converse-chatboxes', {
|
||||
return attrs;
|
||||
},
|
||||
|
||||
async createMessage (message, original_stanza) {
|
||||
/* Create a Backbone.Message object inside this chat box
|
||||
* based on the identified message stanza.
|
||||
*/
|
||||
const attrs = await this.getMessageAttributesFromStanza(message, original_stanza),
|
||||
is_csn = u.isOnlyChatStateNotification(attrs);
|
||||
|
||||
if (is_csn && (attrs.is_delayed || (attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == this.get('nick')))) {
|
||||
// XXX: MUC leakage
|
||||
// No need showing delayed or our own CSN messages
|
||||
return;
|
||||
} else if (!is_csn && !attrs.file && !attrs.plaintext && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
|
||||
// TODO: handle <subject> messages (currently being done by ChatRoom)
|
||||
return;
|
||||
} else {
|
||||
return this.messages.create(attrs);
|
||||
}
|
||||
},
|
||||
|
||||
isHidden () {
|
||||
/* Returns a boolean to indicate whether a newly received
|
||||
* message will be visible to the user or not.
|
||||
@ -680,7 +663,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
});
|
||||
},
|
||||
|
||||
onErrorMessage (message) {
|
||||
async onErrorMessage (message) {
|
||||
/* Handler method for all incoming error message stanzas
|
||||
*/
|
||||
const from_jid = Strophe.getBareJidFromJid(message.getAttribute('from'));
|
||||
@ -708,8 +691,8 @@ converse.plugins.add('converse-chatboxes', {
|
||||
_converse.log('Received an error message without id attribute!', Strophe.LogLevel.ERROR);
|
||||
_converse.log(message, Strophe.LogLevel.ERROR);
|
||||
}
|
||||
chatbox.createMessage(message, message);
|
||||
return true;
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(message, message);
|
||||
chatbox.messages.create(attrs);
|
||||
},
|
||||
|
||||
getMessageBody (stanza) {
|
||||
@ -736,7 +719,7 @@ converse.plugins.add('converse-chatboxes', {
|
||||
_converse.api.send(receipt_stanza);
|
||||
},
|
||||
|
||||
onMessage (stanza) {
|
||||
async onMessage (stanza) {
|
||||
/* Handler method for all incoming single-user chat "message"
|
||||
* stanzas.
|
||||
*
|
||||
@ -816,13 +799,12 @@ converse.plugins.add('converse-chatboxes', {
|
||||
message = msgid && chatbox.messages.findWhere({msgid});
|
||||
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));
|
||||
const attrs = await chatbox.getMessageAttributesFromStanza(stanza, original_stanza);
|
||||
const msg = chatbox.messages.create(attrs);
|
||||
chatbox.incrementUnreadMsgCounter(msg);
|
||||
}
|
||||
}
|
||||
_converse.emit('message', {'stanza': original_stanza, 'chatbox': chatbox});
|
||||
return true;
|
||||
},
|
||||
|
||||
getChatBox (jid, attrs={}, create) {
|
||||
|
@ -218,6 +218,8 @@ converse.plugins.add('converse-mam', {
|
||||
if (!results.length) { return; }
|
||||
this.addSpinner();
|
||||
_converse.api.archive.query(
|
||||
// TODO: only query from the last message we have
|
||||
// in our history
|
||||
_.extend({
|
||||
'groupchat': is_groupchat,
|
||||
'before': '', // Page backwards from the most recent message
|
||||
|
@ -987,33 +987,40 @@ converse.plugins.add('converse-muc', {
|
||||
|
||||
const original_stanza = stanza,
|
||||
forwarded = sizzle(`forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).pop();
|
||||
|
||||
if (forwarded) {
|
||||
stanza = forwarded.querySelector('message');
|
||||
}
|
||||
if (this.isDuplicate(stanza, original_stanza)) {
|
||||
return;
|
||||
}
|
||||
const jid = stanza.getAttribute('from'),
|
||||
resource = Strophe.getResourceFromJid(jid),
|
||||
sender = resource && Strophe.unescapeNode(resource) || '';
|
||||
|
||||
const attrs = await this.getMessageAttributesFromStanza(stanza, original_stanza);
|
||||
if (!attrs.nick) {
|
||||
return;
|
||||
}
|
||||
if (!this.handleMessageCorrection(stanza)) {
|
||||
if (sender === '') {
|
||||
if (attrs.subject && !attrs.thread && !attrs.message) {
|
||||
// https://xmpp.org/extensions/xep-0045.html#subject-mod
|
||||
// -----------------------------------------------------
|
||||
// The subject is changed by sending a message of type "groupchat" to the <room@service>,
|
||||
// where the <message/> MUST contain a <subject/> element that specifies the new subject but
|
||||
// MUST NOT contain a <body/> element (or a <thread/> element).
|
||||
u.safeSave(this, {'subject': {'author': attrs.nick, 'text': attrs.subject || ''}});
|
||||
return;
|
||||
}
|
||||
const subject_el = stanza.querySelector('subject');
|
||||
if (subject_el) {
|
||||
const subject = _.propertyOf(subject_el)('textContent') || '';
|
||||
u.safeSave(this, {'subject': {'author': sender, 'text': subject}});
|
||||
|
||||
const is_csn = u.isOnlyChatStateNotification(attrs),
|
||||
own_message = Strophe.getResourceFromJid(attrs.from) == this.get('nick');
|
||||
if (is_csn && (attrs.is_delayed || own_message)) {
|
||||
// No need showing delayed or our own CSN messages
|
||||
return;
|
||||
}
|
||||
const msg = await this.createMessage(stanza, original_stanza);
|
||||
const msg = await this.messages.create(attrs);
|
||||
if (forwarded && msg && msg.get('sender') === 'me') {
|
||||
msg.save({'received': moment().format()});
|
||||
}
|
||||
this.incrementUnreadMsgCounter(msg);
|
||||
}
|
||||
if (sender !== this.get('nick')) {
|
||||
if (attrs.nick !== this.get('nick')) {
|
||||
// We only emit an event if it's not our own message
|
||||
_converse.emit('message', {'stanza': original_stanza, 'chatbox': this});
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ var specs = [
|
||||
"spec/chatbox",
|
||||
"spec/user-details-modal",
|
||||
"spec/messages",
|
||||
"spec/chatroom",
|
||||
"spec/muc",
|
||||
"spec/room_registration",
|
||||
"spec/autocomplete",
|
||||
"spec/minchats",
|
||||
|
Loading…
Reference in New Issue
Block a user