2
0
Эх сурвалжийг харах

Add timestamps to resources

So that when a higher priority resource goes offline, we can fall back to the
right chat status if at the next priority level there are multiple resources.

https://github.com/jcbrand/converse.js/commit/789654d54e7a8c80b35934f526e05ee7802c790f#comments
JC Brand 8 жил өмнө
parent
commit
4aa123d557
2 өөрчлөгдсөн 173 нэмэгдсэн , 106 устгасан
  1. 162 103
      spec/presence.js
  2. 11 3
      src/converse-core.js

+ 162 - 103
spec/presence.js

@@ -21,115 +21,174 @@
             test_utils.createContacts(_converse, 'current'); // Create some contacts so that we can test positioning
             var contact_jid = mock.cur_names[8].replace(/ /g,'.').toLowerCase() + '@localhost';
             var contact = _converse.roster.get(contact_jid);
-            var stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          from="'+contact_jid+'/c71f218b-0797-4732-8a88-b42cb1d8557a">'+
-            '    <priority>1</priority>'+
-            '    <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" ext="voice-v1 camera-v1 video-v1"'+
-            '       ver="AcN1/PEN8nq7AHD+9jpxMV4U6YM=" node="http://pidgin.im/"/>'+
-            '    <x xmlns="vcard-temp:x:update">'+
-            '        <photo>ce51d94f7f22b87a21274abb93710b9eb7cc1c65</photo>'+
-            '    </x>'+
-            '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T20:26:05Z" from="jabbim.hu"/>'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(contact.get('chat_status')).toBe('online');
-            expect(_.keys(contact.get('resources')).length).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['priority']).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['status']).toBe('online');
+            var stanza;
+            runs(function () {
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          from="'+contact_jid+'/priority-1-resource">'+
+                '    <priority>1</priority>'+
+                '    <c xmlns="http://jabber.org/protocol/caps" hash="sha-1" ext="voice-v1 camera-v1 video-v1"'+
+                '       ver="AcN1/PEN8nq7AHD+9jpxMV4U6YM=" node="http://pidgin.im/"/>'+
+                '    <x xmlns="vcard-temp:x:update">'+
+                '        <photo>ce51d94f7f22b87a21274abb93710b9eb7cc1c65</photo>'+
+                '    </x>'+
+                '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T20:26:05Z" from="jabbim.hu"/>'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(contact.get('chat_status')).toBe('online');
+                expect(_.keys(contact.get('resources')).length).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          id="tYRdj-35"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          from="'+contact_jid+'/androidkhydmcKW">'+
-            '    <status/>'+
-            '    <priority>0</priority>'+
-            '    <show>xa</show>'+
-            '    <c xmlns="http://jabber.org/protocol/caps" ver="GyIX/Kpa4ScVmsZCxRBboJlLAYU=" hash="sha-1"'+
-            '       node="http://www.igniterealtime.org/projects/smack/"/>'+
-            '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T17:02:24Z" from="jabbim.hu"/>'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('online');
-            expect(_.keys(contact.get('resources')).length).toBe(2);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['priority']).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['status']).toBe('online');
-            expect(contact.get('resources')['androidkhydmcKW']['priority']).toBe(0);
-            expect(contact.get('resources')['androidkhydmcKW']['status']).toBe('xa');
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          from="'+contact_jid+'/priority-0-resource">'+
+                '    <status/>'+
+                '    <priority>0</priority>'+
+                '    <show>xa</show>'+
+                '    <c xmlns="http://jabber.org/protocol/caps" ver="GyIX/Kpa4ScVmsZCxRBboJlLAYU=" hash="sha-1"'+
+                '       node="http://www.igniterealtime.org/projects/smack/"/>'+
+                '    <delay xmlns="urn:xmpp:delay" stamp="2017-02-15T17:02:24Z" from="jabbim.hu"/>'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('online');
+                expect(_.keys(contact.get('resources')).length).toBe(2);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          id="tYRdj-35"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          from="'+contact_jid+'/other-resource">'+
-            '    <priority>2</priority>'+
-            '    <show>dnd</show>'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('dnd');
-            expect(_.keys(contact.get('resources')).length).toBe(3);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['priority']).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['status']).toBe('online');
-            expect(contact.get('resources')['androidkhydmcKW']['priority']).toBe(0);
-            expect(contact.get('resources')['androidkhydmcKW']['status']).toBe('xa');
-            expect(contact.get('resources')['other-resource']['priority']).toBe(2);
-            expect(contact.get('resources')['other-resource']['status']).toBe('dnd');
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          from="'+contact_jid+'/priority-2-resource">'+
+                '    <priority>2</priority>'+
+                '    <show>dnd</show>'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('dnd');
+                expect(_.keys(contact.get('resources')).length).toBe(3);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
+                expect(contact.get('resources')['priority-2-resource']['priority']).toBe(2);
+                expect(contact.get('resources')['priority-2-resource']['status']).toBe('dnd');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          id="tYRdj-35"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          from="'+contact_jid+'/other-resource">'+
-            '    <priority>3</priority>'+
-            '    <show>away</show>'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('away');
-            expect(_.keys(contact.get('resources')).length).toBe(3);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['priority']).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['status']).toBe('online');
-            expect(contact.get('resources')['androidkhydmcKW']['priority']).toBe(0);
-            expect(contact.get('resources')['androidkhydmcKW']['status']).toBe('xa');
-            expect(contact.get('resources')['other-resource']['priority']).toBe(3);
-            expect(contact.get('resources')['other-resource']['status']).toBe('away');
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          from="'+contact_jid+'/priority-3-resource">'+
+                '    <priority>3</priority>'+
+                '    <show>away</show>'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('away');
+                expect(_.keys(contact.get('resources')).length).toBe(4);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
+                expect(contact.get('resources')['priority-2-resource']['priority']).toBe(2);
+                expect(contact.get('resources')['priority-2-resource']['status']).toBe('dnd');
+                expect(contact.get('resources')['priority-3-resource']['priority']).toBe(3);
+                expect(contact.get('resources')['priority-3-resource']['status']).toBe('away');
+            });
+            waits(1000); // XXX: Bit of a hack. With jasmine 2 we can mock the date instead.
+            runs(function () {
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          from="'+contact_jid+'/newer-priority-1-resource">'+
+                '    <priority>1</priority>'+
+                '    <show>dnd</show>'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('away');
+                expect(_.keys(contact.get('resources')).length).toBe(5);
+                expect(contact.get('resources')['newer-priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['newer-priority-1-resource']['status']).toBe('dnd');
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
+                expect(contact.get('resources')['priority-2-resource']['priority']).toBe(2);
+                expect(contact.get('resources')['priority-2-resource']['status']).toBe('dnd');
+                expect(contact.get('resources')['priority-3-resource']['priority']).toBe(3);
+                expect(contact.get('resources')['priority-3-resource']['status']).toBe('away');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          type="unavailable"'+
-            '          from="'+contact_jid+'/other-resource">'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('online');
-            expect(_.keys(contact.get('resources')).length).toBe(2);
-            expect(contact.get('resources')['androidkhydmcKW']['priority']).toBe(0);
-            expect(contact.get('resources')['androidkhydmcKW']['status']).toBe('xa');
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['priority']).toBe(1);
-            expect(contact.get('resources')['c71f218b-0797-4732-8a88-b42cb1d8557a']['status']).toBe('online');
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          type="unavailable"'+
+                '          from="'+contact_jid+'/priority-3-resource">'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('dnd');
+                expect(_.keys(contact.get('resources')).length).toBe(4);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
+                expect(contact.get('resources')['priority-2-resource']['priority']).toBe(2);
+                expect(contact.get('resources')['priority-2-resource']['status']).toBe('dnd');
+                expect(contact.get('resources')['newer-priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['newer-priority-1-resource']['status']).toBe('dnd');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          type="unavailable"'+
-            '          from="'+contact_jid+'/c71f218b-0797-4732-8a88-b42cb1d8557a">'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('xa');
-            expect(_.keys(contact.get('resources')).length).toBe(1);
-            expect(contact.get('resources')['androidkhydmcKW']['priority']).toBe(0);
-            expect(contact.get('resources')['androidkhydmcKW']['status']).toBe('xa');
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          type="unavailable"'+
+                '          from="'+contact_jid+'/priority-2-resource">'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('dnd');
+                expect(_.keys(contact.get('resources')).length).toBe(3);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['priority-1-resource']['status']).toBe('online');
+                expect(contact.get('resources')['newer-priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['newer-priority-1-resource']['status']).toBe('dnd');
 
-            stanza = $(
-            '<presence xmlns="jabber:client"'+
-            '          to="dummy@localhost/converse.js-21770972"'+
-            '          type="unavailable"'+
-            '          from="'+contact_jid+'/androidkhydmcKW">'+
-            '</presence>');
-            _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
-            expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('offline');
-            expect(_.keys(contact.get('resources')).length).toBe(0);
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          type="unavailable"'+
+                '          from="'+contact_jid+'/priority-1-resource">'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('dnd');
+                expect(_.keys(contact.get('resources')).length).toBe(2);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+                expect(contact.get('resources')['newer-priority-1-resource']['priority']).toBe(1);
+                expect(contact.get('resources')['newer-priority-1-resource']['status']).toBe('dnd');
+
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          type="unavailable"'+
+                '          from="'+contact_jid+'/newer-priority-1-resource">'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('xa');
+                expect(_.keys(contact.get('resources')).length).toBe(1);
+                expect(contact.get('resources')['priority-0-resource']['priority']).toBe(0);
+                expect(contact.get('resources')['priority-0-resource']['status']).toBe('xa');
+
+                stanza = $(
+                '<presence xmlns="jabber:client"'+
+                '          to="dummy@localhost/converse.js-21770972"'+
+                '          type="unavailable"'+
+                '          from="'+contact_jid+'/priority-0-resource">'+
+                '</presence>');
+                _converse.connection._dataRecv(test_utils.createRequest(stanza[0]));
+                expect(_converse.roster.get(contact_jid).get('chat_status')).toBe('offline');
+                expect(_.keys(contact.get('resources')).length).toBe(0);
+            });
         }));
     });
 }));

+ 11 - 3
src/converse-core.js

@@ -859,8 +859,9 @@
                 var resources = this.get('resources');
                 if (!_.isObject(resources)) { resources = {}; }
                 resources[resource] = {
-                    'priority': _.isNaN(Number(priority)) ? 0 : Number(priority),
-                    'status': chat_status
+                    'priority': _.isNaN(parseInt(priority)) ? 0 : parseInt(priority),
+                    'status': chat_status,
+                    'timestamp': moment().format()
                 };
                 this.set({'resources': resources});
                 return resources;
@@ -884,10 +885,17 @@
             getHighestPriorityStatus: function () {
                 /* Return the chat status assigned to the resource with the
                  * highest priority.
+                 *
+                 * If multiple resources have the same priority, take the
+                 * newest one.
                  */
                 var resources = this.get('resources');
                 if (_.isObject(resources) && _.size(resources)) {
-                    var val = _.flow(_.values, _.partial(_.sortBy, _, 'priority'), _.reverse)(resources)[0];
+                    var val = _.flow(
+                            _.values,
+                            _.partial(_.sortBy, _, ['priority', 'timestamp']),
+                            _.reverse
+                        )(resources)[0];
                     if (!_.isUndefined(val)) {
                         return val.status;
                     }