Przeglądaj źródła

Add tests for src/converse-notification.js. updates #443

In the process refactored the code being tested.

- Move notifications code in MUC to src/converse-notification.js
- Trigger the 'contactStatusChanged' event in RosterContact and not in
  ChatBoxView (which might not exist).
JC Brand 9 lat temu
rodzic
commit
0aa0c02124

+ 1 - 1
docs/source/configuration.rst

@@ -660,7 +660,7 @@ show_desktop_notifications
 * Default: ``true``
 * Default: ``true``
 
 
 Should HTML5 desktop notifications be shown when the browser is not visible or
 Should HTML5 desktop notifications be shown when the browser is not visible or
-blurred?
+not focused?
 
 
 Requires the `src/converse-notification.js` plugin.
 Requires the `src/converse-notification.js` plugin.
 
 

+ 0 - 40
spec/chatroom.js

@@ -192,46 +192,6 @@
                 expect(converse.emit).toHaveBeenCalledWith('message', message.nodeTree);
                 expect(converse.emit).toHaveBeenCalledWith('message', message.nodeTree);
             }.bind(converse));
             }.bind(converse));
 
 
-            it("plays a sound when the current user is mentioned (if configured)", function () {
-                test_utils.openChatRoom('lounge', 'localhost', 'dummy');
-                spyOn(converse, 'emit');
-                converse.play_sounds = true;
-                spyOn(converse, 'playSoundNotification');
-                var view = this.chatboxviews.get('lounge@localhost');
-                if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
-                var text = 'This message will play a sound because it mentions dummy';
-                var message = $msg({
-                    from: 'lounge@localhost/otheruser',
-                    id: '1',
-                    to: 'dummy@localhost',
-                    type: 'groupchat'
-                }).c('body').t(text);
-                view.onChatRoomMessage(message.nodeTree);
-                expect(converse.playSoundNotification).toHaveBeenCalled();
-
-                text = "This message won't play a sound";
-                message = $msg({
-                    from: 'lounge@localhost/otheruser',
-                    id: '2',
-                    to: 'dummy@localhost',
-                    type: 'groupchat'
-                }).c('body').t(text);
-                view.onChatRoomMessage(message.nodeTree);
-                expect(converse.playSoundNotification, 1);
-                converse.play_sounds = false;
-
-                text = "This message won't play a sound because it is sent by dummy";
-                message = $msg({
-                    from: 'lounge@localhost/dummy',
-                    id: '3',
-                    to: 'dummy@localhost',
-                    type: 'groupchat'
-                }).c('body').t(text);
-                view.onChatRoomMessage(message.nodeTree);
-                expect(converse.playSoundNotification, 1);
-                converse.play_sounds = false;
-            }.bind(converse));
-
             it("shows sent groupchat messages", function () {
             it("shows sent groupchat messages", function () {
                 test_utils.openChatRoom('lounge', 'localhost', 'dummy');
                 test_utils.openChatRoom('lounge', 'localhost', 'dummy');
                 spyOn(converse, 'emit');
                 spyOn(converse, 'emit');

+ 109 - 0
spec/notification.js

@@ -0,0 +1,109 @@
+/*global converse */
+(function (root, factory) {
+    define([
+        "jquery",
+        "underscore",
+        "mock",
+        "test_utils"
+        ], function ($, _, mock, test_utils) {
+            return factory($, _, mock, test_utils);
+        }
+    );
+} (this, function ($, _, mock, test_utils) {
+    "use strict";
+    var $msg = converse_api.env.$msg;
+
+    describe("Notifications", function () {
+        // Implement the protocol defined in https://xmpp.org/extensions/xep-0313.html#config
+        beforeEach(function () {
+            runs(function () {
+                test_utils.closeAllChatBoxes();
+                test_utils.createContacts('current');
+            });
+        });
+
+        describe("When show_desktop_notifications is set to true", function () {
+            describe("And the desktop is not focused", function () {
+                describe("an HTML5 Notification", function () {
+
+                    it("is shown when a new message is received", function () {
+                        // TODO: not yet testing show_desktop_notifications setting
+                        spyOn(converse, 'showMessageNotification');
+                        spyOn(converse, 'areDesktopNotificationsEnabled').andReturn(true);
+                        
+                        var message = 'This message will show a desktop notification';
+                        var sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost',
+                            msg = $msg({
+                                from: sender_jid,
+                                to: converse.connection.jid,
+                                type: 'chat',
+                                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'
+                        expect(converse.showMessageNotification).toHaveBeenCalled();
+                    });
+
+                    it("is shown when a user changes their chat state", function () {
+                        // TODO: not yet testing show_desktop_notifications setting
+                        spyOn(converse, 'areDesktopNotificationsEnabled').andReturn(true);
+                        spyOn(converse, 'showChatStateNotification');
+                        var jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
+                        converse.roster.get(jid).set('chat_status', 'busy'); // This will emit 'contactStatusChanged'
+                        expect(converse.showChatStateNotification).toHaveBeenCalled();
+                    });
+                });
+            });
+
+            describe("When a new contact request is received", function () {
+                it("an HTML5 Notification is received", function () {
+                    // TODO
+                });
+            });
+        });
+
+        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", function () {
+                    test_utils.openChatRoom('lounge', 'localhost', 'dummy');
+                    converse.play_sounds = true;
+                    spyOn(converse, 'playSoundNotification');
+                    var view = this.chatboxviews.get('lounge@localhost');
+                    if (!view.$el.find('.chat-area').length) { view.renderChatArea(); }
+                    var text = 'This message will play a sound because it mentions dummy';
+                    var message = $msg({
+                        from: 'lounge@localhost/otheruser',
+                        id: '1',
+                        to: 'dummy@localhost',
+                        type: 'groupchat'
+                    }).c('body').t(text);
+                    view.onChatRoomMessage(message.nodeTree);
+                    expect(converse.playSoundNotification).toHaveBeenCalled();
+
+                    text = "This message won't play a sound";
+                    message = $msg({
+                        from: 'lounge@localhost/otheruser',
+                        id: '2',
+                        to: 'dummy@localhost',
+                        type: 'groupchat'
+                    }).c('body').t(text);
+                    view.onChatRoomMessage(message.nodeTree);
+                    expect(converse.playSoundNotification, 1);
+                    converse.play_sounds = false;
+
+                    text = "This message won't play a sound because it is sent by dummy";
+                    message = $msg({
+                        from: 'lounge@localhost/dummy',
+                        id: '3',
+                        to: 'dummy@localhost',
+                        type: 'groupchat'
+                    }).c('body').t(text);
+                    view.onChatRoomMessage(message.nodeTree);
+                    expect(converse.playSoundNotification, 1);
+                    converse.play_sounds = false;
+                }.bind(converse));
+            });
+        });
+    });
+}));

+ 3 - 1
src/converse-core.js

@@ -868,6 +868,9 @@
                 }, attributes));
                 }, attributes));
 
 
                 this.on('destroy', function () { this.removeFromRoster(); }.bind(this));
                 this.on('destroy', function () { this.removeFromRoster(); }.bind(this));
+                this.on('change:chat_status', function (item) {
+                    converse.emit('contactStatusChanged', item.attributes);
+                });
             },
             },
 
 
             subscribe: function (message) {
             subscribe: function (message) {
@@ -2099,7 +2102,6 @@
                         this.$el.find('div.chat-event').remove();
                         this.$el.find('div.chat-event').remove();
                     }
                     }
                 }
                 }
-                converse.emit('contactStatusChanged', item.attributes);
             },
             },
 
 
             onStatusChanged: function (item) {
             onStatusChanged: function (item) {

+ 1 - 7
src/converse-muc.js

@@ -888,17 +888,14 @@
                 onChatRoomMessage: function (message) {
                 onChatRoomMessage: function (message) {
                     var $message = $(message),
                     var $message = $(message),
                         archive_id = $message.find('result[xmlns="'+Strophe.NS.MAM+'"]').attr('id'),
                         archive_id = $message.find('result[xmlns="'+Strophe.NS.MAM+'"]').attr('id'),
-                        delayed = $message.find('delay').length > 0,
                         $forwarded = $message.find('forwarded'),
                         $forwarded = $message.find('forwarded'),
                         $delay;
                         $delay;
 
 
                     if ($forwarded.length) {
                     if ($forwarded.length) {
                         $message = $forwarded.children('message');
                         $message = $forwarded.children('message');
                         $delay = $forwarded.children('delay');
                         $delay = $forwarded.children('delay');
-                        delayed = $delay.length > 0;
                     }
                     }
-                    var body = $message.children('body').text(),
-                        jid = $message.attr('from'),
+                    var jid = $message.attr('from'),
                         msgid = $message.attr('id'),
                         msgid = $message.attr('id'),
                         resource = Strophe.getResourceFromJid(jid),
                         resource = Strophe.getResourceFromJid(jid),
                         sender = resource && Strophe.unescapeNode(resource) || '',
                         sender = resource && Strophe.unescapeNode(resource) || '',
@@ -920,9 +917,6 @@
                         return true;
                         return true;
                     }
                     }
                     this.model.createMessage($message, $delay, archive_id);
                     this.model.createMessage($message, $delay, archive_id);
-                    if (!delayed && sender !== this.model.get('nick') && (new RegExp("\\b"+this.model.get('nick')+"\\b")).test(body)) {
-                        converse.notifyOfNewMessage();
-                    }
                     if (sender !== this.model.get('nick')) {
                     if (sender !== this.model.get('nick')) {
                         // We only emit an event if it's not our own message
                         // We only emit an event if it's not our own message
                         converse.emit('message', message);
                         converse.emit('message', message);

+ 48 - 15
src/converse-notification.js

@@ -56,11 +56,33 @@
                 );
                 );
             };
             };
 
 
-            converse.shouldNotifyOfNewMessage = function ($message) {
+            converse.shouldNotifyOfGroupMessage = function ($message) {
+                /* Is this a group message worthy of notification?
+                 */
+                var jid = $message.attr('from'),
+                    resource = Strophe.getResourceFromJid(jid),
+                    sender = resource && Strophe.unescapeNode(resource) || '';
+                if (sender === '' || $message.find('delay').length > 0) {
+                    return false;
+                }
+                var room = converse.chatboxes.get(Strophe.getBareJidFromJid(jid));
+                var body = $message.children('body').text();
+                if (sender === room.get('nick') || !(new RegExp("\\b"+room.get('nick')+"\\b")).test(body)) {
+                    return false;
+                }
+                return true;
+            };
+
+            converse.shouldNotifyOfMessage = function ($message) {
+                /* Is this a message worthy of notification?
+                 */
                 var $forwarded = $message.find('forwarded');
                 var $forwarded = $message.find('forwarded');
                 if ($forwarded.length) {
                 if ($forwarded.length) {
                     return false;
                     return false;
                 }
                 }
+                if ($message.attr('type') === 'groupchat') {
+                    return converse.shouldNotifyOfGroupMessage($message);
+                }
                 var is_me = Strophe.getBareJidFromJid($message.attr('from')) === converse.bare_jid;
                 var is_me = Strophe.getBareJidFromJid($message.attr('from')) === converse.bare_jid;
                 return !converse.isOnlyChatStateNotification($message) && !is_me;
                 return !converse.isOnlyChatStateNotification($message) && !is_me;
             };
             };
@@ -83,16 +105,17 @@
                 }
                 }
             };
             };
 
 
+            converse.areDesktopNotificationsEnabled = function () {
+                return (supports_html5_notification &&
+                        converse.show_desktop_notifications &&
+                        converse.windowState === 'blur' &&
+                        Notification.permission === "granted");
+            };
+
             converse.showMessageNotification = function ($message) {
             converse.showMessageNotification = function ($message) {
                 /* Shows an HTML5 Notification to indicate that a new chat
                 /* Shows an HTML5 Notification to indicate that a new chat
                  * message was received.
                  * message was received.
                  */
                  */
-                if (!supports_html5_notification ||
-                        !converse.show_desktop_notifications ||
-                        converse.windowState !== 'blur' ||
-                        Notification.permission !== "granted") {
-                    return;
-                }
                 var contact_jid = Strophe.getBareJidFromJid($message.attr('from'));
                 var contact_jid = Strophe.getBareJidFromJid($message.attr('from'));
                 var roster_item = converse.roster.get(contact_jid);
                 var roster_item = converse.roster.get(contact_jid);
                 var n = new Notification(__(___("%1$s says"), roster_item.get('fullname')), {
                 var n = new Notification(__(___("%1$s says"), roster_item.get('fullname')), {
@@ -103,10 +126,9 @@
                 setTimeout(n.close.bind(n), 5000);
                 setTimeout(n.close.bind(n), 5000);
             };
             };
 
 
-            converse.handleChatStateNotification = function (evt, contact) {
-                /* Event handler for on('contactStatusChanged').
-                 * Will show an HTML5 notification to indicate that the chat
-                 * status has changed.
+            converse.showChatStateNotification = function (contact) {
+                /* Creates an HTML5 Notification to inform of a change in a
+                 * contact's chat state.
                  */
                  */
                 var chat_state = contact.chat_status,
                 var chat_state = contact.chat_status,
                     message = null;
                     message = null;
@@ -130,21 +152,32 @@
                 setTimeout(n.close.bind(n), 5000);
                 setTimeout(n.close.bind(n), 5000);
             };
             };
 
 
+            converse.handleChatStateNotification = function (evt, contact) {
+                /* Event handler for on('contactStatusChanged').
+                 * Will show an HTML5 notification to indicate that the chat
+                 * status has changed.
+                 */
+                if (converse.areDesktopNotificationsEnabled()) {
+                    converse.showChatStateNotification();
+                }
+            };
 
 
-            converse.handleNewMessageNotification = function (evt, message) {
+            converse.handleMessageNotification = function (evt, message) {
                 /* Event handler for the on('message') event. Will call methods
                 /* Event handler for the on('message') event. Will call methods
                  * to play sounds and show HTML5 notifications.
                  * to play sounds and show HTML5 notifications.
                  */
                  */
                 var $message = $(message);
                 var $message = $(message);
-                if (!converse.shouldNotifyOfNewMessage($message)) {
+                if (!converse.shouldNotifyOfMessage($message)) {
                     return false;
                     return false;
                 }
                 }
                 converse.playSoundNotification($message);
                 converse.playSoundNotification($message);
-                converse.showMessageNotification($message);
+                if (converse.areDesktopNotificationsEnabled()) {
+                    converse.showMessageNotification($message);
+                }
             };
             };
 
 
             converse.on('contactStatusChanged',  converse.handleChatStateNotification);
             converse.on('contactStatusChanged',  converse.handleChatStateNotification);
-            converse.on('message',  converse.handleNewMessageNotification);
+            converse.on('message',  converse.handleMessageNotification);
         }
         }
     });
     });
 }));
 }));

+ 1 - 0
tests/main.js

@@ -70,6 +70,7 @@ require([
                 "spec/chatbox",
                 "spec/chatbox",
                 "spec/chatroom",
                 "spec/chatroom",
                 "spec/minchats",
                 "spec/minchats",
+                "spec/notification",
                 "spec/profiling",
                 "spec/profiling",
                 "spec/ping",
                 "spec/ping",
                 "spec/register",
                 "spec/register",