Sfoglia il codice sorgente

Make sure the roster is fetched again if stream resumption fails

JC Brand 5 anni fa
parent
commit
99805d2510
4 ha cambiato i file con 77 aggiunte e 10 eliminazioni
  1. 69 10
      spec/smacks.js
  2. 2 0
      src/headless/converse-roster.js
  3. 5 0
      src/headless/converse-smacks.js
  4. 1 0
      tests/mock.js

+ 69 - 10
spec/smacks.js

@@ -54,23 +54,27 @@
                 `<iq from="romeo@montague.lit" id="${disco_iq.getAttribute('id')}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
                     `<pubsub xmlns="http://jabber.org/protocol/pubsub"><items node="eu.siacs.conversations.axolotl.devicelist"/></pubsub></iq>`);
 
-            iq = IQ_stanzas.pop();
+            iq = IQ_stanzas[IQ_stanzas.length-1];
             expect(Strophe.serialize(iq)).toBe(
                 `<iq id="${iq.getAttribute('id')}" type="get" xmlns="jabber:client"><query xmlns="jabber:iq:roster"/></iq>`);
 
+            await test_utils.waitForRoster(_converse, 'current', 1);
+
             expect(sent_stanzas.filter(s => (s.nodeName === 'r')).length).toBe(2);
-            expect(_converse.session.get('unacked_stanzas').length).toBe(4);
+            expect(_converse.session.get('unacked_stanzas').length).toBe(5);
 
             // test handling of acks
             let ack = u.toStanza(`<a xmlns="urn:xmpp:sm:3" h="1"/>`);
             _converse.connection._dataRecv(test_utils.createRequest(ack));
-            expect(_converse.session.get('unacked_stanzas').length).toBe(3);
+            expect(_converse.session.get('unacked_stanzas').length).toBe(4);
 
             // test handling of ack requests
             let r = u.toStanza(`<r xmlns="urn:xmpp:sm:3"/>`);
             _converse.connection._dataRecv(test_utils.createRequest(r));
+
             ack = await u.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a')).pop());
-            expect(Strophe.serialize(ack)).toBe('<a h="0" xmlns="urn:xmpp:sm:3"/>');
+            expect(Strophe.serialize(ack)).toBe('<a h="1" xmlns="urn:xmpp:sm:3"/>');
+
 
             const disco_result = $iq({
                 'type': 'result',
@@ -88,7 +92,7 @@
 
             ack = u.toStanza(`<a xmlns="urn:xmpp:sm:3" h="2"/>`);
             _converse.connection._dataRecv(test_utils.createRequest(ack));
-            expect(_converse.session.get('unacked_stanzas').length).toBe(2);
+            expect(_converse.session.get('unacked_stanzas').length).toBe(3);
 
             r = u.toStanza(`<r xmlns="urn:xmpp:sm:3"/>`);
             _converse.connection._dataRecv(test_utils.createRequest(r));
@@ -99,15 +103,14 @@
             _converse.connection.IQ_stanzas = [];
             IQ_stanzas = _converse.connection.IQ_stanzas;
             _converse.api.connection.reconnect();
-            stanza = await u.waitUntil(() =>
-                sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
-            expect(Strophe.serialize(stanza)).toEqual('<resume h="1" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
+            stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
+            expect(Strophe.serialize(stanza)).toEqual('<resume h="2" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
 
             result = u.toStanza(`<resumed xmlns="urn:xmpp:sm:3" h="another-sequence-number" previd="some-long-sm-id"/>`);
             _converse.connection._dataRecv(test_utils.createRequest(result));
 
             // Another <enable> stanza doesn't get sent out
-            expect(sizzle('enable', sent_stanzas).length).toBe(0);
+            expect(sent_stanzas.filter(s => (s.tagName === 'enable')).length).toBe(1);
             expect(_converse.session.get('smacks_enabled')).toBe(true);
 
             await u.waitUntil(() => IQ_stanzas.length === 2);
@@ -119,11 +122,67 @@
                     `<query xmlns="http://jabber.org/protocol/disco#info"/></iq>`);
 
             // We don't fetch the roster again because it's cached.
-            expect(_converse.session.get('roster_fetched')).toBeFalsy();
+            expect(_converse.session.get('roster_fetched')).toBeTruthy();
             expect(IQ_stanzas.filter(iq => sizzle('query[xmlns="jabber:iq:roster"]', iq).pop()).length).toBe(0);
 
             await _converse.api.waitUntil('statusInitialized');
             done();
         }));
+
+
+        it("might not resume and the session will then be reset",
+            mock.initConverse(
+                ['chatBoxesInitialized'],
+                { 'auto_login': false,
+                  'enable_smacks': true,
+                  'show_controlbox_by_default': true,
+                  'smacks_max_unacked_stanzas': 2
+                },
+                async function (done, _converse) {
+
+            const view = _converse.chatboxviews.get('controlbox');
+            spyOn(view, 'renderControlBoxPane').and.callThrough();
+
+            _converse.api.user.login('romeo@montague.lit/orchard', 'secret');
+            const sent_stanzas = _converse.connection.sent_stanzas;
+            let stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'enable')).pop());
+            expect(Strophe.serialize(stanza)).toEqual('<enable resume="true" xmlns="urn:xmpp:sm:3"/>');
+            let result = u.toStanza(`<enabled xmlns="urn:xmpp:sm:3" id="some-long-sm-id" resume="true"/>`);
+            _converse.connection._dataRecv(test_utils.createRequest(result));
+
+            await test_utils.waitForRoster(_converse, 'current', 1);
+
+            // test session resumption
+            _converse.api.connection.reconnect();
+            stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
+            expect(Strophe.serialize(stanza)).toEqual('<resume h="1" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
+
+            result = u.toStanza(
+                `<failed xmlns="urn:xmpp:sm:3" h="another-sequence-number">`+
+                    `<item-not-found xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>`+
+                `</failed>`);
+            _converse.connection._dataRecv(test_utils.createRequest(result));
+
+            // Session data gets reset
+            expect(_converse.session.get('smacks_enabled')).toBe(false);
+            expect(_converse.session.get('num_stanzas_handled')).toBe(0);
+            expect(_converse.session.get('num_stanzas_handled_by_server')).toBe(0);
+            expect(_converse.session.get('num_stanzas_since_last_ack')).toBe(0);
+            expect(_converse.session.get('unacked_stanzas').length).toBe(0);
+            expect(_converse.session.get('roster_fetched')).toBeFalsy();
+
+            await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'enable')).length === 2);
+            stanza = sent_stanzas.filter(s => (s.tagName === 'enable')).pop();
+            expect(Strophe.serialize(stanza)).toEqual('<enable resume="true" xmlns="urn:xmpp:sm:3"/>');
+
+            result = u.toStanza(`<enabled xmlns="urn:xmpp:sm:3" id="another-long-sm-id" resume="true"/>`);
+
+            _converse.connection._dataRecv(test_utils.createRequest(result));
+            expect(_converse.session.get('smacks_enabled')).toBe(true);
+
+            // Check that the roster gets fetched
+            await test_utils.waitForRoster(_converse, 'current', 1);
+            done();
+        }));
     });
 }));

+ 2 - 0
src/headless/converse-roster.js

@@ -939,6 +939,8 @@ converse.plugins.add('converse-roster', {
             }
         }
 
+        _converse.api.listen.on('streamResumptionFailed', () => _converse.session.set('roster_fetched', false));
+
         _converse.api.listen.on('clearSession', () => {
             clearPresences();
             if (_converse.shouldClearCache()) {

+ 5 - 0
src/headless/converse-smacks.js

@@ -132,6 +132,11 @@ converse.plugins.add('converse-smacks', {
                 _converse.log(el.outerHTML, Strophe.LogLevel.ERROR);
             }
             resetSessionData();
+            /**
+             * Triggered when the XEP-0198 stream could not be resumed.
+             * @event _converse#streamResumptionFailed
+             */
+             _converse.api.trigger('streamResumptionFailed');
             return true;
         }
 

+ 1 - 0
tests/mock.js

@@ -262,6 +262,7 @@
             try {
                 await func(_done, _converse);
             } catch(e) {
+                console.error(e);
                 fail(e);
                 _done();
             }