فهرست منبع

Store the roster version

updates #1106
JC Brand 7 سال پیش
والد
کامیت
e8a26eb185
3فایلهای تغییر یافته به همراه57 افزوده شده و 11 حذف شده
  1. 1 1
      spec/protocol.js
  2. 37 0
      spec/roster.js
  3. 19 10
      src/converse-roster.js

+ 1 - 1
spec/protocol.js

@@ -210,7 +210,7 @@
                      *  </iq>
                      */
                     spyOn(_converse.roster, "updateContact").and.callThrough();
-                    stanza = $iq({'type': 'set', 'from': 'dummy@localhost'})
+                    stanza = $iq({'type': 'set', 'from': _converse.connection.jid})
                         .c('query', {'xmlns': 'jabber:iq:roster'})
                         .c('item', {
                             'jid': 'contact@example.org',

+ 37 - 0
spec/roster.js

@@ -35,6 +35,43 @@
 
     describe("The Contacts Roster", function () {
 
+        it("supports roster versioning",
+            mock.initConverseWithPromises(
+                null, ['rosterGroupsFetched'], {},
+                function (done, _converse) {
+
+            var IQ_stanzas = _converse.connection.IQ_stanzas;
+            var stanza;
+
+            test_utils.waitUntil(() => {
+                const node = _.filter(IQ_stanzas, function (iq) {
+                    return iq.nodeTree.querySelector('iq query[xmlns="jabber:iq:roster"]');
+                }).pop();
+                if (node) {
+                    stanza = node.nodeTree;
+                    return true;
+                }
+            }).then(() => {
+                expect(_converse.roster.data.get('version')).toBeUndefined();
+                expect(stanza.outerHTML).toBe(
+                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster"/>`+
+                    `</iq>`);
+                const result = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                }).c('query', {
+                    'xmlns': 'jabber:iq:roster',
+                    'ver': 'ver7'
+                }).c('item', {'jid': 'nurse@example.com'}).up()
+                  .c('item', {'jid': 'romeo@example.com'})
+                _converse.connection._dataRecv(test_utils.createRequest(result));
+                expect(_converse.roster.data.get('version')).toBe('ver7');
+                done();
+            });
+        }));
+
         describe("The live filter", function () {
 
             it("will only appear when roster contacts flow over the visible area",

+ 19 - 10
src/converse-roster.js

@@ -48,6 +48,13 @@
                 _converse.roster = new _converse.RosterContacts();
                 _converse.roster.browserStorage = new Backbone.BrowserStorage[_converse.storage](
                     b64_sha1(`converse.contacts-${_converse.bare_jid}`));
+
+                _converse.roster.data = new Backbone.Model();
+                const id = b64_sha1(`converse-roster-model-${_converse.bare_jid}`);
+                _converse.roster.data.id = id;
+                _converse.roster.data.browserStorage = new Backbone.BrowserStorage[_converse.storage](id);
+                _converse.roster.data.fetch();
+
                 _converse.rostergroups = new _converse.RosterGroups();
                 _converse.rostergroups.browserStorage = new Backbone.BrowserStorage[_converse.storage](
                     b64_sha1(`converse.roster.groups${_converse.bare_jid}`));
@@ -330,18 +337,18 @@
 
                 onConnected () {
                     /* Called as soon as the connection has been established
-                    * (either after initial login, or after reconnection).
-                    *
-                    * Use the opportunity to register stanza handlers.
-                    */
+                     * (either after initial login, or after reconnection).
+                     *
+                     * Use the opportunity to register stanza handlers.
+                     */
                     this.registerRosterHandler();
                     this.registerRosterXHandler();
                 },
 
                 registerRosterHandler () {
                     /* Register a handler for roster IQ "set" stanzas, which update
-                    * roster contacts.
-                    */
+                     * roster contacts.
+                     */
                     _converse.connection.addHandler((iq) => {
                         _converse.roster.onRosterPush(iq);
                         return true;
@@ -350,8 +357,8 @@
 
                 registerRosterXHandler () {
                     /* Register a handler for RosterX message stanzas, which are
-                    * used to suggest roster contacts to a user.
-                    */
+                     * used to suggest roster contacts to a user.
+                     */
                     let t = 0;
                     _converse.connection.addHandler(
                         function (msg) {
@@ -560,8 +567,10 @@
                     /* An IQ stanza containing the roster has been received from
                      * the XMPP server.
                      */
-                    const items = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"] item`, iq);
-                    _.each(items, this.updateContact.bind(this));
+                    const query = sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, iq).pop(),
+                          items = sizzle(`item`, query);
+                    _.each(items, (item) => this.updateContact(item));
+                    this.data.save('version', query.getAttribute('ver'));
                     _converse.emit('roster', iq);
                 },