diff --git a/spec/smacks.js b/spec/smacks.js index f22ed77d9..4a00fe53e 100644 --- a/spec/smacks.js +++ b/spec/smacks.js @@ -54,23 +54,27 @@ ``+ ``); - iq = IQ_stanzas.pop(); + iq = IQ_stanzas[IQ_stanzas.length-1]; expect(Strophe.serialize(iq)).toBe( ``); + 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(``); _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(``); _converse.connection._dataRecv(test_utils.createRequest(r)); + ack = await u.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a')).pop()); - expect(Strophe.serialize(ack)).toBe(''); + expect(Strophe.serialize(ack)).toBe(''); + const disco_result = $iq({ 'type': 'result', @@ -88,7 +92,7 @@ ack = u.toStanza(``); _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(``); _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(''); + stanza = await u.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'resume')).pop()); + expect(Strophe.serialize(stanza)).toEqual(''); result = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(result)); // Another 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 @@ ``); // 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(''); + let result = u.toStanza(``); + _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(''); + + result = u.toStanza( + ``+ + ``+ + ``); + _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(''); + + result = u.toStanza(``); + + _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(); + })); }); })); diff --git a/src/headless/converse-roster.js b/src/headless/converse-roster.js index 470c23227..67b5039a9 100644 --- a/src/headless/converse-roster.js +++ b/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()) { diff --git a/src/headless/converse-smacks.js b/src/headless/converse-smacks.js index 8019cf4bb..321088716 100644 --- a/src/headless/converse-smacks.js +++ b/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; } diff --git a/tests/mock.js b/tests/mock.js index c314b7d3e..bda400c2f 100644 --- a/tests/mock.js +++ b/tests/mock.js @@ -262,6 +262,7 @@ try { await func(_done, _converse); } catch(e) { + console.error(e); fail(e); _done(); }