Browse Source

implement /destroy command in muc

Christoph Scholz 6 years ago
parent
commit
eacd7fd933
4 changed files with 92 additions and 2 deletions
  1. 1 0
      CHANGES.md
  2. 25 1
      dist/converse.js
  3. 50 1
      spec/chatroom.js
  4. 16 0
      src/converse-muc-views.js

+ 1 - 0
CHANGES.md

@@ -14,6 +14,7 @@
 - #1378 Message Delivery Receipts were being sent for carbons and own messages
 - #1378 Message Delivery Receipts were being sent for carbons and own messages
 - #1379 MUC unread messages indicator is failing
 - #1379 MUC unread messages indicator is failing
 - #1382 Message Delivery Receipts: Set store hint and type='chat'
 - #1382 Message Delivery Receipts: Set store hint and type='chat'
+- #1388 implement muc-owner command `/destroy`
 
 
 
 
 ## 4.0.6 (2018-12-07)
 ## 4.0.6 (2018-12-07)

+ 25 - 1
dist/converse.js

@@ -54247,6 +54247,22 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
         }
         }
       },
       },
 
 
+      destroy(groupchat, reason, onSuccess, onError) {
+        const destroy = $build("destroy");
+        const iq = $iq({
+          to: groupchat,
+          type: "set"
+        }).c("query", {
+          xmlns: Strophe.NS.MUC_OWNER
+        }).cnode(destroy.node);
+
+        if (reason && reason.length > 0) {
+          iq.c("reason", reason);
+        }
+
+        return _converse.api.sendIQ(iq);
+      },
+
       modifyRole(groupchat, nick, role, reason, onSuccess, onError) {
       modifyRole(groupchat, nick, role, reason, onSuccess, onError) {
         const item = $build("item", {
         const item = $build("item", {
           nick,
           nick,
@@ -54359,8 +54375,16 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_3__["default"].plugins
             this.modifyRole(this.model.get('jid'), args[0], 'participant', args[1], undefined, this.onCommandError.bind(this));
             this.modifyRole(this.model.get('jid'), args[0], 'participant', args[1], undefined, this.onCommandError.bind(this));
             break;
             break;
 
 
+          case 'destroy':
+            if (!this.verifyAffiliations(['owner'])) {
+              break;
+            }
+
+            this.destroy(this.model.get('jid'), args[0]).then(() => this.close()).catch(e => this.onCommandError(e));
+            break;
+
           case 'help':
           case 'help':
-            this.showHelpMessages([`<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`, `<strong>/ban</strong>: ${__('Ban user from groupchat')}`, `<strong>/clear</strong>: ${__('Remove messages')}`, `<strong>/deop</strong>: ${__('Change user role to participant')}`, `<strong>/help</strong>: ${__('Show this menu')}`, `<strong>/kick</strong>: ${__('Kick user from groupchat')}`, `<strong>/me</strong>: ${__('Write in 3rd person')}`, `<strong>/member</strong>: ${__('Grant membership to a user')}`, `<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`, `<strong>/nick</strong>: ${__('Change your nickname')}`, `<strong>/op</strong>: ${__('Grant moderator role to user')}`, `<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`, `<strong>/register</strong>: ${__("Register a nickname for this groupchat")}`, `<strong>/revoke</strong>: ${__("Revoke user's membership")}`, `<strong>/subject</strong>: ${__('Set groupchat subject')}`, `<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`, `<strong>/voice</strong>: ${__('Allow muted user to post messages')}`]);
+            this.showHelpMessages([`<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`, `<strong>/ban</strong>: ${__('Ban user from groupchat')}`, `<strong>/clear</strong>: ${__('Remove messages')}`, `<strong>/deop</strong>: ${__('Change user role to participant')}`, `<strong>/destroy</strong>: ${__('Destroy room')}`, `<strong>/help</strong>: ${__('Show this menu')}`, `<strong>/kick</strong>: ${__('Kick user from groupchat')}`, `<strong>/me</strong>: ${__('Write in 3rd person')}`, `<strong>/member</strong>: ${__('Grant membership to a user')}`, `<strong>/mute</strong>: ${__("Remove user's ability to post messages")}`, `<strong>/nick</strong>: ${__('Change your nickname')}`, `<strong>/op</strong>: ${__('Grant moderator role to user')}`, `<strong>/owner</strong>: ${__('Grant ownership of this groupchat')}`, `<strong>/register</strong>: ${__("Register a nickname for this groupchat")}`, `<strong>/revoke</strong>: ${__("Revoke user's membership")}`, `<strong>/subject</strong>: ${__('Set groupchat subject')}`, `<strong>/topic</strong>: ${__('Set groupchat subject (alias for /subject)')}`, `<strong>/voice</strong>: ${__('Allow muted user to post messages')}`]);
             break;
             break;
 
 
           case 'kick':
           case 'kick':

+ 50 - 1
spec/chatroom.js

@@ -2544,7 +2544,7 @@
                 });
                 });
 
 
                 const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
                 const info_messages = Array.prototype.slice.call(view.el.querySelectorAll('.chat-info'), 0);
-                expect(info_messages.length).toBe(18);
+                expect(info_messages.length).toBe(19);
                 expect(info_messages.pop().textContent).toBe('/voice: Allow muted user to post messages');
                 expect(info_messages.pop().textContent).toBe('/voice: Allow muted user to post messages');
                 expect(info_messages.pop().textContent).toBe('/topic: Set groupchat subject (alias for /subject)');
                 expect(info_messages.pop().textContent).toBe('/topic: Set groupchat subject (alias for /subject)');
                 expect(info_messages.pop().textContent).toBe('/subject: Set groupchat subject');
                 expect(info_messages.pop().textContent).toBe('/subject: Set groupchat subject');
@@ -2558,6 +2558,7 @@
                 expect(info_messages.pop().textContent).toBe('/me: Write in 3rd person');
                 expect(info_messages.pop().textContent).toBe('/me: Write in 3rd person');
                 expect(info_messages.pop().textContent).toBe('/kick: Kick user from groupchat');
                 expect(info_messages.pop().textContent).toBe('/kick: Kick user from groupchat');
                 expect(info_messages.pop().textContent).toBe('/help: Show this menu');
                 expect(info_messages.pop().textContent).toBe('/help: Show this menu');
+                expect(info_messages.pop().textContent).toBe('/destroy: Destroy room');
                 expect(info_messages.pop().textContent).toBe('/deop: Change user role to participant');
                 expect(info_messages.pop().textContent).toBe('/deop: Change user role to participant');
                 expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
                 expect(info_messages.pop().textContent).toBe('/clear: Remove messages');
                 expect(info_messages.pop().textContent).toBe('/ban: Ban user from groupchat');
                 expect(info_messages.pop().textContent).toBe('/ban: Ban user from groupchat');
@@ -3326,6 +3327,54 @@
                 expect(info_msgs.pop().textContent).toBe("annoyingGuy has been given a voice again");
                 expect(info_msgs.pop().textContent).toBe("annoyingGuy has been given a voice again");
                 done();
                 done();
             }));
             }));
+
+            it("takes /destroy to destroy a muc",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    async function (done, _converse) {
+
+                await test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy');
+                let sent_IQ, IQ_id;
+                const sendIQ = _converse.connection.sendIQ;
+                spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
+                    sent_IQ = iq;
+                    IQ_id = sendIQ.bind(this)(iq, callback, errback);
+                });
+                const view = _converse.chatboxviews.get('lounge@localhost');
+                const textarea = view.el.querySelector('.chat-textarea');
+                textarea.value = '/destroy bored';
+                view.onFormSubmitted(new Event('submit'));
+                expect(sent_IQ.toLocaleString()).toBe(
+                    `<iq id="${IQ_id}" to="lounge@localhost" type="set" xmlns="jabber:client">`+
+                        `<query xmlns="http://jabber.org/protocol/muc#owner">`+
+                            `<destroy>`+
+                                `<reason>`+
+                                    `bored`+
+                                `</reason>`+
+                            `</destroy>`+
+                        `</query>`+
+                    `</iq>`);
+
+                /* <iq from="lounge@localhost"
+                 *  id="${IQ_id}"
+                 *  to="dummy@localhost/resource"
+                 *  type="result"
+                 *  xmlns="jabber:client"/>
+                */
+                const result_stanza = $iq({
+                    'type': 'result',
+                    'id': IQ_id,
+                    'from': view.model.get('jid'),
+                    'to': _converse.connection.jid
+                });
+                spyOn(view, 'close').and.callThrough();
+                spyOn(_converse, 'emit');
+                _converse.connection._dataRecv(test_utils.createRequest(result_stanza));
+                await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
+                expect(view.close).toHaveBeenCalled();
+                expect(_converse.emit).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
+                done();
+            }));
         });
         });
 
 
         describe("When attempting to enter a groupchat", function () {
         describe("When attempting to enter a groupchat", function () {

+ 16 - 0
src/converse-muc-views.js

@@ -797,6 +797,13 @@ converse.plugins.add('converse-muc-views', {
                 }
                 }
             },
             },
 
 
+            destroy (groupchat, reason, onSuccess, onError) {
+                const destroy = $build("destroy");
+                const iq = $iq({to: groupchat, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_OWNER}).cnode(destroy.node);
+                if (reason && reason.length > 0) { iq.c("reason", reason); }
+                return _converse.api.sendIQ(iq);
+            },
+
             modifyRole (groupchat, nick, role, reason, onSuccess, onError) {
             modifyRole (groupchat, nick, role, reason, onSuccess, onError) {
                 const item = $build("item", {nick, role});
                 const item = $build("item", {nick, role});
                 const iq = $iq({to: groupchat, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_ADMIN}).cnode(item.node);
                 const iq = $iq({to: groupchat, type: "set"}).c("query", {xmlns: Strophe.NS.MUC_ADMIN}).cnode(item.node);
@@ -884,12 +891,21 @@ converse.plugins.add('converse-muc-views', {
                                 this.model.get('jid'), args[0], 'participant', args[1],
                                 this.model.get('jid'), args[0], 'participant', args[1],
                                 undefined, this.onCommandError.bind(this));
                                 undefined, this.onCommandError.bind(this));
                         break;
                         break;
+                    case 'destroy':
+                        if (!this.verifyAffiliations(['owner'])) {
+                            break;
+                        }
+                        this.destroy(this.model.get('jid'), args[0])
+                            .then(() => this.close())
+                            .catch(e => this.onCommandError(e));
+                        break;
                     case 'help':
                     case 'help':
                         this.showHelpMessages([
                         this.showHelpMessages([
                             `<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
                             `<strong>/admin</strong>: ${__("Change user's affiliation to admin")}`,
                             `<strong>/ban</strong>: ${__('Ban user from groupchat')}`,
                             `<strong>/ban</strong>: ${__('Ban user from groupchat')}`,
                             `<strong>/clear</strong>: ${__('Remove messages')}`,
                             `<strong>/clear</strong>: ${__('Remove messages')}`,
                             `<strong>/deop</strong>: ${__('Change user role to participant')}`,
                             `<strong>/deop</strong>: ${__('Change user role to participant')}`,
+                            `<strong>/destroy</strong>: ${__('Destroy room')}`,
                             `<strong>/help</strong>: ${__('Show this menu')}`,
                             `<strong>/help</strong>: ${__('Show this menu')}`,
                             `<strong>/kick</strong>: ${__('Kick user from groupchat')}`,
                             `<strong>/kick</strong>: ${__('Kick user from groupchat')}`,
                             `<strong>/me</strong>: ${__('Write in 3rd person')}`,
                             `<strong>/me</strong>: ${__('Write in 3rd person')}`,