(function (root, factory) { define(["jasmine", "mock", "test-utils"], factory); } (this, function (jasmine, mock, test_utils) { "use strict"; const $iq = converse.env.$iq; const Strophe = converse.env.Strophe; const sizzle = converse.env.sizzle; const u = converse.env.utils; describe("XEP-0198 Stream Management", function () { it("gets enabled with an stanza and resumed with a stanza", mock.initConverse( null, ['connectionInitialized', '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 test_utils.waitUntil(() => sent_stanzas.filter(s => (s.tagName === 'enable')).pop()); expect(_converse.session.get('smacks_enabled')).toBe(false); expect(Strophe.serialize(stanza)).toEqual(''); let result = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(result)); expect(_converse.session.get('smacks_enabled')).toBe(true); await test_utils.waitUntil(() => view.renderControlBoxPane.calls.count()); let IQ_stanzas = _converse.connection.IQ_stanzas; await test_utils.waitUntil(() => IQ_stanzas.length === 4); let iq = IQ_stanzas.pop(); expect(Strophe.serialize(iq)).toBe( ``+ ``); iq = IQ_stanzas.pop(); expect(Strophe.serialize(iq)).toBe( ``); iq = IQ_stanzas.pop(); expect(Strophe.serialize(iq)).toBe( ``+ ``); const disco_iq = IQ_stanzas.pop(); expect(Strophe.serialize(disco_iq)).toBe( ``+ ``); expect(sent_stanzas.filter(s => (s.nodeName === 'r')).length).toBe(2); expect(_converse.session.get('unacked_stanzas').length).toBe(4); // test handling of acks let ack = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(ack)); expect(_converse.session.get('unacked_stanzas').length).toBe(3); // test handling of ack requests let r = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(r)); ack = await test_utils.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a')).pop()); expect(Strophe.serialize(ack)).toBe(''); const disco_result = $iq({ 'type': 'result', 'from': 'montague.lit', 'to': 'romeo@montague.lit/orchard', 'id': disco_iq.getAttribute('id'), }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info'}) .c('identity', { 'category': 'server', 'type': 'im' }).up() .c('feature', {'var': 'http://jabber.org/protocol/disco#info'}).up() .c('feature', {'var': 'http://jabber.org/protocol/disco#items'}); _converse.connection._dataRecv(test_utils.createRequest(disco_result)); ack = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(ack)); expect(_converse.session.get('unacked_stanzas').length).toBe(2); r = u.toStanza(``); _converse.connection._dataRecv(test_utils.createRequest(r)); ack = await test_utils.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a' && s.getAttribute('h') === '1')).pop()); expect(Strophe.serialize(ack)).toBe(''); // test session resumption _converse.connection.IQ_stanzas = []; IQ_stanzas = _converse.connection.IQ_stanzas; _converse.api.connection.reconnect(); stanza = await test_utils.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(_converse.session.get('smacks_enabled')).toBe(true); await test_utils.waitUntil(() => IQ_stanzas.length === 2); // Test that unacked stanzas get resent out iq = IQ_stanzas.pop(); expect(Strophe.serialize(iq)).toBe( ``+ ``); iq = IQ_stanzas.pop(); expect(Strophe.serialize(iq)).toBe( ``); await _converse.api.waitUntil('statusInitialized'); done(); })); }); }));