/*global mock */ describe("Service Discovery", function () { describe("Whenever converse.js queries a server for its features", function () { it("stores the features it receives", mock.initConverse( ['discoInitialized'], {}, async function (done, _converse) { const { u, $iq } = converse.env; const IQ_stanzas = _converse.connection.IQ_stanzas; const IQ_ids = _converse.connection.IQ_ids; await u.waitUntil(function () { return IQ_stanzas.filter(function (iq) { return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]'); }).length > 0; }); /* * * * * * * * * * * * * * */ let stanza = IQ_stanzas.find(function (iq) { return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]'); }); const info_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)]; stanza = $iq({ 'type': 'result', 'from': 'montague.lit', 'to': 'romeo@montague.lit/orchard', 'id': info_IQ_id }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info'}) .c('identity', { 'category': 'server', 'type': 'im'}).up() .c('identity', { 'category': 'conference', 'type': 'text', 'name': 'Play-Specific Chatrooms'}).up() .c('identity', { 'category': 'directory', 'type': 'chatroom', 'name': 'Play-Specific Chatrooms'}).up() .c('feature', { 'var': 'http://jabber.org/protocol/disco#info'}).up() .c('feature', { 'var': 'http://jabber.org/protocol/disco#items'}).up() .c('feature', { 'var': 'jabber:iq:register'}).up() .c('feature', { 'var': 'jabber:iq:time'}).up() .c('feature', { 'var': 'jabber:iq:version'}); _converse.connection._dataRecv(mock.createRequest(stanza)); let entities = await _converse.api.disco.entities.get() expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID expect(entities.get(_converse.domain).features.length).toBe(5); expect(entities.get(_converse.domain).identities.length).toBe(3); expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:version'}).length).toBe(1); expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:time'}).length).toBe(1); expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:register'}).length).toBe(1); expect(entities.get('montague.lit').features.where( {'var': 'http://jabber.org/protocol/disco#items'}).length).toBe(1); expect(entities.get('montague.lit').features.where( {'var': 'http://jabber.org/protocol/disco#info'}).length).toBe(1); await u.waitUntil(function () { // Converse.js sees that the entity has a disco#items feature, // so it will make a query for it. return IQ_stanzas.filter(iq => iq.querySelector('query[xmlns="http://jabber.org/protocol/disco#items"]')).length > 0; }); /* * * * * * * * * * * * */ stanza = IQ_stanzas.find(function (iq) { return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#items"]'); }); const items_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)]; stanza = $iq({ 'type': 'result', 'from': 'montague.lit', 'to': 'romeo@montague.lit/orchard', 'id': items_IQ_id }).c('query', {'xmlns': 'http://jabber.org/protocol/disco#items'}) .c('item', { 'jid': 'people.shakespeare.lit', 'name': 'Directory of Characters'}).up() .c('item', { 'jid': 'plays.shakespeare.lit', 'name': 'Play-Specific Chatrooms'}).up() .c('item', { 'jid': 'words.shakespeare.lit', 'name': 'Gateway to Marlowe IM'}).up() .c('item', { 'jid': 'montague.lit', 'node': 'books', 'name': 'Books by and about Shakespeare'}).up() .c('item', { 'node': 'montague.lit', 'name': 'Wear your literary taste with pride'}).up() .c('item', { 'jid': 'montague.lit', 'node': 'music', 'name': 'Music from the time of Shakespeare' }); _converse.connection._dataRecv(mock.createRequest(stanza)); await u.waitUntil(() => _converse.disco_entities); entities = _converse.disco_entities; expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID expect(entities.get(_converse.domain).items.length).toBe(3); expect(entities.get(_converse.domain).items.pluck('jid').includes('people.shakespeare.lit')).toBeTruthy(); expect(entities.get(_converse.domain).items.pluck('jid').includes('plays.shakespeare.lit')).toBeTruthy(); expect(entities.get(_converse.domain).items.pluck('jid').includes('words.shakespeare.lit')).toBeTruthy(); expect(entities.get(_converse.domain).identities.where({'category': 'conference'}).length).toBe(1); expect(entities.get(_converse.domain).identities.where({'category': 'directory'}).length).toBe(1); done(); })); }); describe("Whenever converse.js discovers a new server feature", function () { it("emits the serviceDiscovered event", mock.initConverse( ['discoInitialized'], {}, function (done, _converse) { const { Strophe } = converse.env; sinon.spy(_converse.api, "trigger"); _converse.disco_entities.get(_converse.domain).features.create({'var': Strophe.NS.MAM}); expect(_converse.api.trigger.called).toBe(true); expect(_converse.api.trigger.args[0][0]).toBe('serviceDiscovered'); expect(_converse.api.trigger.args[0][1].get('var')).toBe(Strophe.NS.MAM); done(); })); }); });