Przeglądaj źródła

Add subscribe/unsubscribe pubsub api methods

JC Brand 1 miesiąc temu
rodzic
commit
f9ab7d75e7

+ 41 - 2
src/headless/plugins/pubsub/api.js

@@ -5,7 +5,7 @@
 import converse from '../../shared/api/public.js';
 import _converse from '../../shared/_converse.js';
 import api from '../../shared/api/index.js';
-import log from "@converse/log";
+import log from '@converse/log';
 import { parseErrorStanza } from '../../shared/parsers.js';
 import { parseStanzaForPubSubConfig } from './parsers.js';
 
@@ -176,7 +176,8 @@ export default {
                 const e = await parseErrorStanza(iq);
                 if (
                     e.name === 'conflict' &&
-                    /** @type {import('shared/errors').StanzaError} */(e).extra[Strophe.NS.PUBSUB_ERROR] === 'precondition-not-met'
+                    /** @type {import('shared/errors').StanzaError} */ (e).extra[Strophe.NS.PUBSUB_ERROR] ===
+                        'precondition-not-met'
                 ) {
                     // Manually configure the node if we can't set it via publish-options
                     await api.pubsub.config.set(entity_jid, node, options);
@@ -198,5 +199,43 @@ export default {
                 }
             }
         },
+        /**
+         * Subscribes the local user to a PubSub node.
+         *
+         * @method _converse.api.pubsub.subscribe
+         * @param {string} jid - PubSub service JID.
+         * @param {string} node - The node to subscribe to
+         * @returns {Promise<void>}
+         */
+        async subscribe(jid, node) {
+            const service = jid || (await api.disco.entities.find('http://jabber.org/protocol/pubsub'));
+            const own_jid = _converse.session.get('jid');
+            const iq = stx`
+                <iq type="set" from="${own_jid}" to="${service}" xmlns="jabber:client">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <subscribe node="${node}" jid="${own_jid}"/>
+                  </pubsub>
+                </iq>`;
+            await api.sendIQ(iq);
+        },
+
+        /**
+         * Unsubscribes the local user from a PubSub node.
+         *
+         * @method _converse.api.pubsub.unsubscribe
+         * @param {string} jid - The PubSub service JID
+         * @param {string} node - The node to unsubscribe from
+         * @returns {Promise<void>}
+         */
+        async unsubscribe(jid, node) {
+            const own_jid = _converse.session.get('jid');
+            const iq = stx`
+                <iq type="set" from="${own_jid}" to="${jid}" xmlns="jabber:client">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <unsubscribe node="${node}" jid="${own_jid}"/>
+                  </pubsub>
+                </iq>`;
+            await api.sendIQ(iq);
+        },
     },
 };

+ 78 - 0
src/headless/plugins/pubsub/tests/api.js

@@ -0,0 +1,78 @@
+/* global converse */
+import mock from '../../../tests/mock.js';
+
+const { stx, Strophe } = converse.env;
+
+describe('pubsub subscribe/unsubscribe API', function () {
+    beforeAll(() => jasmine.addMatchers({ toEqualStanza: jasmine.toEqualStanza }));
+
+    it(
+        'sends correct IQ for subscribe',
+        mock.initConverse([], {}, async function (_converse) {
+            await mock.waitForRoster(_converse, 'current', 0);
+            const { api, state } = _converse;
+            const own_jid = state.session.get('jid');
+            const sent = api.connection.get().sent_stanzas;
+            const service = 'pubsub.example.org';
+            const node = 'testnode';
+            const subscribePromise = api.pubsub.subscribe(service, node);
+
+            const stanza = sent.filter((iq) => iq.querySelector('pubsub subscribe')).pop();
+            expect(stanza).toEqualStanza(stx`
+                <iq type="set"
+                    from="${own_jid}"
+                    to="${service}"
+                    xmlns="jabber:client"
+                    id="${stanza.getAttribute('id')}">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <subscribe node="${node}" jid="${own_jid}"/>
+                  </pubsub>
+                </iq>`);
+
+            _converse.api.connection.get()._dataRecv(
+                mock.createRequest(stx`
+                <iq type="result"
+                    xmlns="jabber:client"
+                    from="${service}"
+                    to="${own_jid}"
+                    id="${stanza.getAttribute('id')}"/>
+            `)
+            );
+            await subscribePromise;
+        })
+    );
+
+    it(
+        'sends correct IQ for unsubscribe',
+        mock.initConverse([], {}, async function (_converse) {
+            await mock.waitForRoster(_converse, 'current', 0);
+            const { api, state } = _converse;
+            const own_jid = state.session.get('jid');
+            const sent = api.connection.get().sent_stanzas;
+            const service = 'pubsub.example.org';
+            const node = 'testnode';
+            const unsubscribePromise = api.pubsub.unsubscribe(service, node);
+            const stanza = sent.filter((iq) => iq.querySelector('pubsub unsubscribe')).pop();
+            _converse.api.connection.get()._dataRecv(
+                mock.createRequest(stx`
+                <iq type="result"
+                    xmlns="jabber:client"
+                    from="${service}"
+                    to="${own_jid}"
+                    id="${stanza.getAttribute('id')}"/>
+            `)
+            );
+            await unsubscribePromise;
+            expect(stanza).toEqualStanza(stx`
+                <iq type="set"
+                    from="${own_jid}"
+                    to="${service}"
+                    xmlns="jabber:client"
+                    id="${stanza.getAttribute('id')}">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <unsubscribe node="${node}" jid="${own_jid}"/>
+                  </pubsub>
+                </iq>`);
+        })
+    );
+});

+ 18 - 0
src/headless/types/plugins/pubsub/api.d.ts

@@ -34,6 +34,24 @@ declare namespace _default {
          * @returns {Promise<void|Element>}
          */
         function publish(jid: string, node: string, item: import("strophe.js").Builder | import("strophe.js").Stanza | (import("strophe.js").Builder | import("strophe.js").Stanza)[], options: import("./types").PubSubConfigOptions, strict_options?: boolean): Promise<void | Element>;
+        /**
+         * Subscribes the local user to a PubSub node.
+         *
+         * @method _converse.api.pubsub.subscribe
+         * @param {string} jid - PubSub service JID.
+         * @param {string} node - The node to subscribe to
+         * @returns {Promise<void>}
+         */
+        function subscribe(jid: string, node: string): Promise<void>;
+        /**
+         * Unsubscribes the local user from a PubSub node.
+         *
+         * @method _converse.api.pubsub.unsubscribe
+         * @param {string} jid - The PubSub service JID
+         * @param {string} node - The node to unsubscribe from
+         * @returns {Promise<void>}
+         */
+        function unsubscribe(jid: string, node: string): Promise<void>;
     }
 }
 export default _default;