2020-09-10 10:09:30 +02:00
|
|
|
/*global mock, converse */
|
2020-04-22 13:11:48 +02:00
|
|
|
|
2020-11-05 14:44:22 +01:00
|
|
|
const { Strophe, _ } = converse.env;
|
2020-04-22 13:11:48 +02:00
|
|
|
const $msg = converse.env.$msg;
|
|
|
|
const u = converse.env.utils;
|
|
|
|
|
|
|
|
describe("Notifications", function () {
|
|
|
|
// Implement the protocol defined in https://xmpp.org/extensions/xep-0313.html#config
|
|
|
|
|
|
|
|
describe("When show_desktop_notifications is set to true", function () {
|
|
|
|
describe("And the desktop is not focused", function () {
|
|
|
|
describe("an HTML5 Notification", function () {
|
2016-03-08 11:42:52 +01:00
|
|
|
|
2020-04-22 13:11:48 +02:00
|
|
|
it("is shown when a new private message is received",
|
|
|
|
mock.initConverse(['rosterGroupsFetched'], {}, async (done, _converse) => {
|
|
|
|
|
|
|
|
await mock.waitForRoster(_converse, 'current');
|
|
|
|
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
2017-04-05 11:01:31 +02:00
|
|
|
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
2020-04-22 13:11:48 +02:00
|
|
|
spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
|
|
|
|
|
|
|
|
const message = 'This message will show a desktop notification';
|
|
|
|
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
|
|
|
msg = $msg({
|
|
|
|
from: sender_jid,
|
|
|
|
to: _converse.connection.jid,
|
|
|
|
type: 'chat',
|
|
|
|
id: u.getUniqueId()
|
|
|
|
}).c('body').t(message).up()
|
|
|
|
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
|
|
|
|
await _converse.handleMessageStanza(msg); // This will emit 'message'
|
|
|
|
await u.waitUntil(() => _converse.api.chatviews.get(sender_jid));
|
2016-12-20 10:30:20 +01:00
|
|
|
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
2020-04-22 13:11:48 +02:00
|
|
|
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
2019-02-12 14:21:45 +01:00
|
|
|
done();
|
2016-11-03 11:01:09 +01:00
|
|
|
}));
|
2016-03-08 11:42:52 +01:00
|
|
|
|
2020-04-22 13:11:48 +02:00
|
|
|
it("is shown when you are mentioned in a groupchat",
|
2019-10-11 16:38:01 +02:00
|
|
|
mock.initConverse(['rosterGroupsFetched'], {}, async (done, _converse) => {
|
2017-07-11 10:41:11 +02:00
|
|
|
|
2020-04-22 13:11:48 +02:00
|
|
|
await mock.waitForRoster(_converse, 'current');
|
|
|
|
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
|
|
|
const view = _converse.api.chatviews.get('lounge@montague.lit');
|
2018-10-26 10:15:01 +02:00
|
|
|
if (!view.el.querySelectorAll('.chat-area').length) {
|
|
|
|
view.renderChatArea();
|
|
|
|
}
|
2020-04-22 13:11:48 +02:00
|
|
|
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);
|
|
|
|
|
2020-08-26 00:02:53 +02:00
|
|
|
// Test mention with setting false
|
|
|
|
const nick = mock.chatroom_names[0];
|
|
|
|
const makeMsg = text => $msg({
|
|
|
|
from: 'lounge@montague.lit/'+nick,
|
|
|
|
id: u.getUniqueId(),
|
|
|
|
to: 'romeo@montague.lit',
|
|
|
|
type: 'groupchat'
|
|
|
|
}).c('body').t(text).tree();
|
|
|
|
_converse.connection._dataRecv(mock.createRequest(makeMsg('romeo: this will NOT show a notification')));
|
2020-05-15 14:33:31 +02:00
|
|
|
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
2020-08-26 00:02:53 +02:00
|
|
|
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 0);
|
|
|
|
expect(_converse.showMessageNotification).not.toHaveBeenCalled();
|
2020-04-22 13:11:48 +02:00
|
|
|
|
2020-08-26 00:02:53 +02:00
|
|
|
// Test reference
|
|
|
|
const message_with_ref = $msg({
|
|
|
|
from: 'lounge@montague.lit/'+nick,
|
|
|
|
id: u.getUniqueId(),
|
|
|
|
to: 'romeo@montague.lit',
|
|
|
|
type: 'groupchat'
|
|
|
|
}).c('body').t('romeo: this will show a notification').up()
|
|
|
|
.c('reference', {'xmlns':'urn:xmpp:reference:0', 'begin':'0', 'end':'5', 'type':'mention', 'uri':'xmpp:romeo@montague.lit'}).tree();
|
|
|
|
_converse.connection._dataRecv(mock.createRequest(message_with_ref));
|
|
|
|
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
2020-04-22 13:11:48 +02:00
|
|
|
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
|
|
|
|
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
2020-08-26 00:02:53 +02:00
|
|
|
|
|
|
|
// Test mention with setting true
|
|
|
|
_converse.api.settings.set('notify_all_room_messages', true);
|
|
|
|
_converse.connection._dataRecv(mock.createRequest(makeMsg('romeo: this will show a notification')));
|
|
|
|
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
|
|
|
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 2);
|
|
|
|
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
2020-04-22 13:11:48 +02:00
|
|
|
if (no_notification) {
|
|
|
|
delete window.Notification;
|
|
|
|
}
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
|
|
|
|
it("is shown for headline messages",
|
|
|
|
mock.initConverse(['rosterGroupsFetched'], {}, async (done, _converse) => {
|
|
|
|
|
|
|
|
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
|
|
|
spyOn(_converse, 'isMessageToHiddenChat').and.returnValue(true);
|
|
|
|
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
|
|
|
const stanza = $msg({
|
|
|
|
'type': 'headline',
|
|
|
|
'from': 'notify.example.com',
|
|
|
|
'to': 'romeo@montague.lit',
|
|
|
|
'xml:lang': 'en'
|
|
|
|
})
|
|
|
|
.c('subject').t('SIEVE').up()
|
|
|
|
.c('body').t('<juliet@example.com> You got mail.').up()
|
|
|
|
.c('x', {'xmlns': 'jabber:x:oob'})
|
|
|
|
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
|
|
|
|
_converse.connection._dataRecv(mock.createRequest(stanza));
|
2020-10-28 13:05:39 +01:00
|
|
|
|
2020-04-22 13:11:48 +02:00
|
|
|
await u.waitUntil(() => _converse.chatboxviews.keys().length);
|
|
|
|
const view = _converse.chatboxviews.get('notify.example.com');
|
2020-05-15 14:33:31 +02:00
|
|
|
await new Promise(resolve => view.model.messages.once('rendered', resolve));
|
2020-04-24 17:33:32 +02:00
|
|
|
expect(_converse.chatboxviews.keys().includes('notify.example.com')).toBeTruthy();
|
2020-04-22 13:11:48 +02:00
|
|
|
expect(_converse.showMessageNotification).toHaveBeenCalled();
|
2018-10-26 10:15:01 +02:00
|
|
|
done();
|
2016-11-03 11:01:09 +01:00
|
|
|
}));
|
2020-04-22 13:11:48 +02:00
|
|
|
|
|
|
|
it("is not shown for full JID headline messages if allow_non_roster_messaging is false", mock.initConverse((done, _converse) => {
|
|
|
|
_converse.allow_non_roster_messaging = false;
|
|
|
|
spyOn(_converse, 'showMessageNotification').and.callThrough();
|
|
|
|
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
|
|
|
const stanza = $msg({
|
|
|
|
'type': 'headline',
|
|
|
|
'from': 'someone@notify.example.com',
|
|
|
|
'to': 'romeo@montague.lit',
|
|
|
|
'xml:lang': 'en'
|
|
|
|
})
|
|
|
|
.c('subject').t('SIEVE').up()
|
|
|
|
.c('body').t('<juliet@example.com> You got mail.').up()
|
|
|
|
.c('x', {'xmlns': 'jabber:x:oob'})
|
|
|
|
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
|
|
|
|
_converse.connection._dataRecv(mock.createRequest(stanza));
|
|
|
|
expect(
|
|
|
|
_.includes(_converse.chatboxviews.keys(),
|
|
|
|
'someone@notify.example.com')
|
|
|
|
).toBeFalsy();
|
|
|
|
expect(_converse.showMessageNotification).not.toHaveBeenCalled();
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
|
|
|
|
it("is shown when a user changes their chat state (if show_chat_state_notifications is true)",
|
|
|
|
mock.initConverse(['rosterGroupsFetched'], {show_chat_state_notifications: true},
|
|
|
|
async (done, _converse) => {
|
|
|
|
|
|
|
|
await mock.waitForRoster(_converse, 'current', 3);
|
|
|
|
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
|
|
|
spyOn(_converse, 'showChatStateNotification');
|
|
|
|
const jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
|
|
|
_converse.roster.get(jid).presence.set('show', 'busy'); // This will emit 'contactStatusChanged'
|
|
|
|
await u.waitUntil(() => _converse.areDesktopNotificationsEnabled.calls.count() === 1);
|
|
|
|
expect(_converse.showChatStateNotification).toHaveBeenCalled();
|
|
|
|
done()
|
|
|
|
}));
|
2016-03-08 11:42:52 +01:00
|
|
|
});
|
|
|
|
});
|
2020-04-22 13:11:48 +02:00
|
|
|
|
|
|
|
describe("When a new contact request is received", function () {
|
|
|
|
it("an HTML5 Notification is received", mock.initConverse((done, _converse) => {
|
|
|
|
spyOn(_converse, 'areDesktopNotificationsEnabled').and.returnValue(true);
|
|
|
|
spyOn(_converse, 'showContactRequestNotification');
|
|
|
|
_converse.api.trigger('contactRequest', {'fullname': 'Peter Parker', 'jid': 'peter@parker.com'});
|
|
|
|
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
|
|
|
|
expect(_converse.showContactRequestNotification).toHaveBeenCalled();
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
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 groupchat",
|
|
|
|
mock.initConverse(['rosterGroupsFetched'], {}, async (done, _converse) => {
|
|
|
|
|
|
|
|
mock.createContacts(_converse, 'current');
|
|
|
|
await mock.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
|
|
|
|
_converse.play_sounds = true;
|
|
|
|
spyOn(_converse, 'playSoundNotification');
|
|
|
|
const view = _converse.chatboxviews.get('lounge@montague.lit');
|
|
|
|
if (!view.el.querySelectorAll('.chat-area').length) {
|
|
|
|
view.renderChatArea();
|
|
|
|
}
|
|
|
|
let text = 'This message will play a sound because it mentions romeo';
|
|
|
|
let message = $msg({
|
|
|
|
from: 'lounge@montague.lit/otheruser',
|
|
|
|
id: '1',
|
|
|
|
to: 'romeo@montague.lit',
|
|
|
|
type: 'groupchat'
|
|
|
|
}).c('body').t(text);
|
2020-08-26 00:02:53 +02:00
|
|
|
_converse.api.settings.set('notify_all_room_messages', true);
|
2020-04-24 17:33:32 +02:00
|
|
|
await view.model.handleMessageStanza(message.nodeTree);
|
2020-04-22 13:11:48 +02:00
|
|
|
await u.waitUntil(() => _converse.playSoundNotification.calls.count());
|
|
|
|
expect(_converse.playSoundNotification).toHaveBeenCalled();
|
|
|
|
|
|
|
|
text = "This message won't play a sound";
|
|
|
|
message = $msg({
|
|
|
|
from: 'lounge@montague.lit/otheruser',
|
|
|
|
id: '2',
|
|
|
|
to: 'romeo@montague.lit',
|
|
|
|
type: 'groupchat'
|
|
|
|
}).c('body').t(text);
|
2020-04-24 17:33:32 +02:00
|
|
|
await view.model.handleMessageStanza(message.nodeTree);
|
2020-04-22 13:11:48 +02:00
|
|
|
expect(_converse.playSoundNotification, 1);
|
|
|
|
_converse.play_sounds = false;
|
|
|
|
|
|
|
|
text = "This message won't play a sound because it is sent by romeo";
|
|
|
|
message = $msg({
|
|
|
|
from: 'lounge@montague.lit/romeo',
|
|
|
|
id: '3',
|
|
|
|
to: 'romeo@montague.lit',
|
|
|
|
type: 'groupchat'
|
|
|
|
}).c('body').t(text);
|
2020-04-24 17:33:32 +02:00
|
|
|
await view.model.handleMessageStanza(message.nodeTree);
|
2020-04-22 13:11:48 +02:00
|
|
|
expect(_converse.playSoundNotification, 1);
|
|
|
|
_converse.play_sounds = false;
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
});
|
2016-03-08 11:42:52 +01:00
|
|
|
});
|
2020-11-05 14:44:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
describe("A Favicon Message Counter", function () {
|
|
|
|
|
|
|
|
it("is incremented when the message is received and the window is not focused",
|
|
|
|
mock.initConverse(
|
|
|
|
['rosterGroupsFetched'], {'update_title': false},
|
|
|
|
async function (done, _converse) {
|
|
|
|
|
|
|
|
await mock.waitForRoster(_converse, 'current');
|
|
|
|
await mock.openControlBox(_converse);
|
|
|
|
|
|
|
|
const favico = jasmine.createSpyObj('favico', ['badge']);
|
|
|
|
spyOn(converse.env, 'Favico').and.returnValue(favico);
|
|
|
|
|
|
|
|
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
|
|
|
const previous_state = _converse.windowState;
|
|
|
|
const msg = $msg({
|
|
|
|
from: sender_jid,
|
|
|
|
to: _converse.connection.jid,
|
|
|
|
type: 'chat',
|
|
|
|
id: u.getUniqueId()
|
|
|
|
}).c('body').t('This message will increment the message counter').up()
|
|
|
|
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
|
|
|
_converse.windowState = 'hidden';
|
|
|
|
|
|
|
|
spyOn(_converse.api, "trigger").and.callThrough();
|
|
|
|
|
|
|
|
await _converse.handleMessageStanza(msg);
|
|
|
|
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
|
|
|
|
|
|
|
|
expect(favico.badge.calls.count()).toBe(0);
|
|
|
|
|
|
|
|
_converse.api.settings.set('update_title', true);
|
|
|
|
const msg2 = $msg({
|
|
|
|
from: sender_jid,
|
|
|
|
to: _converse.connection.jid,
|
|
|
|
type: 'chat',
|
|
|
|
id: u.getUniqueId()
|
|
|
|
}).c('body').t('This message increment the message counter AND update the page title').up()
|
|
|
|
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
|
|
|
|
|
|
|
await _converse.handleMessageStanza(msg2);
|
|
|
|
await u.waitUntil(() => favico.badge.calls.count() === 1);
|
|
|
|
expect(favico.badge.calls.mostRecent().args.pop()).toBe(2);
|
|
|
|
|
|
|
|
const view = _converse.chatboxviews.get(sender_jid);
|
|
|
|
expect(view.model.get('num_unread')).toBe(2);
|
|
|
|
|
|
|
|
// Check that it's cleared when the window is focused
|
|
|
|
_converse.windowState = 'hidden';
|
|
|
|
_converse.saveWindowState({'type': 'focus'});
|
|
|
|
await u.waitUntil(() => favico.badge.calls.count() === 2);
|
|
|
|
expect(favico.badge.calls.mostRecent().args.pop()).toBe(0);
|
|
|
|
|
|
|
|
expect(view.model.get('num_unread')).toBe(0);
|
|
|
|
_converse.windowSate = previous_state;
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
|
|
|
|
it("is not incremented when the message is received and the window is focused",
|
|
|
|
mock.initConverse(
|
|
|
|
['rosterGroupsFetched'], {},
|
|
|
|
async function (done, _converse) {
|
|
|
|
|
|
|
|
await mock.waitForRoster(_converse, 'current');
|
|
|
|
await mock.openControlBox(_converse);
|
|
|
|
|
|
|
|
const favico = jasmine.createSpyObj('favico', ['badge']);
|
|
|
|
spyOn(converse.env, 'Favico').and.returnValue(favico);
|
|
|
|
|
|
|
|
_converse.saveWindowState({'type': 'focus'});
|
|
|
|
const message = 'This message will not increment the message counter';
|
|
|
|
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit',
|
|
|
|
msg = $msg({
|
|
|
|
from: sender_jid,
|
|
|
|
to: _converse.connection.jid,
|
|
|
|
type: 'chat',
|
|
|
|
id: u.getUniqueId()
|
|
|
|
}).c('body').t(message).up()
|
|
|
|
.c('active', {'xmlns': Strophe.NS.CHATSTATES}).tree();
|
|
|
|
await _converse.handleMessageStanza(msg);
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
const view = _converse.chatboxviews.get(sender_jid);
|
|
|
|
expect(view.model.get('num_unread')).toBe(0);
|
|
|
|
expect(favico.badge.calls.count()).toBe(0);
|
|
|
|
done();
|
|
|
|
}, 500);
|
|
|
|
}));
|
|
|
|
|
|
|
|
it("is incremented from zero when chatbox was closed after viewing previously received messages and the window is not focused now",
|
|
|
|
mock.initConverse(
|
|
|
|
['rosterGroupsFetched'], {},
|
|
|
|
async function (done, _converse) {
|
|
|
|
|
|
|
|
await mock.waitForRoster(_converse, 'current');
|
|
|
|
|
|
|
|
const favico = jasmine.createSpyObj('favico', ['badge']);
|
|
|
|
spyOn(converse.env, 'Favico').and.returnValue(favico);
|
|
|
|
|
|
|
|
const message = 'This message will always increment the message counter from zero';
|
|
|
|
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
|
|
|
|
const msgFactory = function () {
|
|
|
|
return $msg({
|
|
|
|
from: sender_jid,
|
|
|
|
to: _converse.connection.jid,
|
|
|
|
type: 'chat',
|
|
|
|
id: u.getUniqueId()
|
|
|
|
})
|
|
|
|
.c('body').t(message).up()
|
|
|
|
.c('active', {'xmlns': Strophe.NS.CHATSTATES})
|
|
|
|
.tree();
|
|
|
|
};
|
|
|
|
|
|
|
|
// leave converse-chat page
|
|
|
|
_converse.windowState = 'hidden';
|
|
|
|
await _converse.handleMessageStanza(msgFactory());
|
|
|
|
let view = _converse.chatboxviews.get(sender_jid);
|
|
|
|
await u.waitUntil(() => favico.badge.calls.count() === 1, 1000);
|
|
|
|
expect(favico.badge.calls.mostRecent().args.pop()).toBe(1);
|
|
|
|
|
|
|
|
// come back to converse-chat page
|
|
|
|
_converse.saveWindowState({'type': 'focus'});
|
|
|
|
await u.waitUntil(() => u.isVisible(view.el));
|
|
|
|
await u.waitUntil(() => favico.badge.calls.count() === 2);
|
|
|
|
expect(favico.badge.calls.mostRecent().args.pop()).toBe(0);
|
|
|
|
|
|
|
|
// close chatbox and leave converse-chat page again
|
|
|
|
view.close();
|
|
|
|
_converse.windowState = 'hidden';
|
|
|
|
|
|
|
|
// check that msg_counter is incremented from zero again
|
|
|
|
await _converse.handleMessageStanza(msgFactory());
|
|
|
|
view = _converse.chatboxviews.get(sender_jid);
|
|
|
|
await u.waitUntil(() => u.isVisible(view.el));
|
|
|
|
await u.waitUntil(() => favico.badge.calls.count() === 3);
|
|
|
|
expect(favico.badge.calls.mostRecent().args.pop()).toBe(1);
|
|
|
|
done();
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
2020-04-22 12:10:39 +02:00
|
|
|
});
|