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();
}