Browse Source

Add `api.pubsub.subscriptions` to fetch pubsub subscriptions

JC Brand 4 weeks ago
parent
commit
f0c380336f

+ 1 - 1
docs/source/style_guide.rst

@@ -5,7 +5,7 @@
 Software Style Guide
 ====================
 
-Most of the style guide recommendations here come from Douglas Crockford's book
+Many of the style guide recommendations here come from Douglas Crockford's book
 `JavaScript, the good parts <http://shop.oreilly.com/product/9780596517748.do>`_
 
 Tabs or spaces?

+ 32 - 1
src/headless/plugins/pubsub/api.js

@@ -251,7 +251,6 @@ export default {
 
         /**
          * 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
@@ -267,5 +266,37 @@ export default {
                 </iq>`;
             await api.sendIQ(iq);
         },
+
+        /**
+         * Retrieves the subscriptions for the local user.
+         * @method _converse.api.pubsub.subscriptions
+         * @param {string} [jid] - The PubSub service JID.
+         * @param {string} [node] - The node to retrieve subscriptions from.
+         * @returns {Promise<import('./types').PubSubSubscription[]>}
+         */
+        async subscriptions(jid, node) {
+            const service = jid || (await api.disco.entities.find(Strophe.NS.PUBSUB));
+            const own_jid = _converse.session.get('jid');
+            const iq = stx`
+                <iq xmlns="jabber:client"
+                    type="get"
+                    from="${own_jid}"
+                    to="${service}">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <subscriptions${node ? ` node="${node}"` : ''}/>
+                  </pubsub>
+                </iq>`;
+            const response = await api.sendIQ(iq);
+            const subs_el = response.querySelector('pubsub subscriptions');
+            if (!subs_el) return [];
+
+            const subs = Array.from(subs_el.querySelectorAll('subscription')).map((el) => ({
+                node: el.getAttribute('node'),
+                jid: el.getAttribute('jid'),
+                subscription: el.getAttribute('subscription'),
+                subid: el.hasAttribute('subid') ? el.getAttribute('subid') : undefined,
+            }));
+            return subs;
+        },
     },
 };

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

@@ -120,4 +120,50 @@ describe('pubsub subscribe/unsubscribe API', function () {
             await createPromise;
         })
     );
+
+    it(
+        'retrieves correct IQ for retrieve subscriptions',
+        mock.initConverse([], {}, async function (_converse) {
+            await mock.waitForRoster(_converse, 'current', 0);
+            const { api, state } = _converse;
+            const service = 'pubsub.example.org';
+            const bare_jid = state.session.get('jid');
+            const subscriptionsPromise = api.pubsub.subscriptions(service);
+            const stanza = api.connection
+                .get()
+                .sent_stanzas.filter((iq) => iq.querySelector('pubsub subscriptions'))
+                .pop();
+            expect(stanza).toEqualStanza(stx`
+                <iq type="get"
+                    from="${bare_jid}"
+                    to="${service}"
+                    xmlns="jabber:client"
+                    id="${stanza.getAttribute('id')}">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <subscriptions/>
+                  </pubsub>
+                </iq>`);
+            _converse.api.connection.get()._dataRecv(
+                mock.createRequest(stx`
+                <iq type="result"
+                    xmlns="jabber:client"
+                    from="${service}"
+                    to="${bare_jid}"
+                    id="${stanza.getAttribute('id')}">
+                  <pubsub xmlns="${Strophe.NS.PUBSUB}">
+                    <subscriptions>
+                      <subscription node="node1" jid="${bare_jid}" subscription="subscribed"/>
+                      <subscription node="node2" jid="${bare_jid}" subscription="unconfigured" subid="sid1"/>
+                    </subscriptions>
+                  </pubsub>
+                </iq>
+            `)
+            );
+            const subs = await subscriptionsPromise;
+            expect(subs).toEqual([
+                { node: 'node1', jid: bare_jid, subscription: 'subscribed', subid: undefined },
+                { node: 'node2', jid: bare_jid, subscription: 'unconfigured', subid: 'sid1' },
+            ]);
+        })
+    );
 });

+ 7 - 0
src/headless/plugins/pubsub/types.ts

@@ -40,3 +40,10 @@ export type PubSubConfigOptions = {
     // Specify the semantic type of payload data to be provided at this node.
     type?: string;
 };
+
+export type PubSubSubscription = {
+    node: string;
+    jid: string;
+    subscription: 'subscribed'|'unconfigured';
+    subid?: string;
+};

+ 8 - 1
src/headless/types/plugins/pubsub/api.d.ts

@@ -53,13 +53,20 @@ declare namespace _default {
         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>;
+        /**
+         * Retrieves the subscriptions for the local user.
+         * @method _converse.api.pubsub.subscriptions
+         * @param {string} [jid] - The PubSub service JID.
+         * @param {string} [node] - The node to retrieve subscriptions from.
+         * @returns {Promise<import('./types').PubSubSubscription[]>}
+         */
+        function subscriptions(jid?: string, node?: string): Promise<import("./types").PubSubSubscription[]>;
     }
 }
 export default _default;

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

@@ -21,4 +21,10 @@ export type PubSubConfigOptions = {
     title?: string;
     type?: string;
 };
+export type PubSubSubscription = {
+    node: string;
+    jid: string;
+    subscription: 'subscribed' | 'unconfigured';
+    subid?: string;
+};
 //# sourceMappingURL=types.d.ts.map