From 12d6785d02438f2d9b889b6f14888d24ef197719 Mon Sep 17 00:00:00 2001 From: JC Brand Date: Mon, 12 Oct 2015 14:23:05 +0000 Subject: [PATCH] Fixes #472 Cannot read property 'splitOnce' of undefined --- converse.js | 29 ++++++++++++++++++++-- docs/CHANGES.rst | 3 ++- spec/chatroom.js | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/converse.js b/converse.js index b8f3a73c7..13a36acc8 100644 --- a/converse.js +++ b/converse.js @@ -2896,6 +2896,21 @@ return this.setAffiliation(room, jid, 'admin', reason, handler_cb, error_cb); }, + validateRoleChangeCommand: function (command, args) { + /* Check that a command to change a chat room user's role or + * affiliation has anough arguments. + */ + // TODO check if first argument is valid + if (args.length < 1 || args.length > 2) { + this.showStatusNotification( + __("Error: the \""+command+"\" command takes two arguments, the user's nickname and optionally a reason."), + true + ); + return false; + } + return true; + }, + onChatRoomMessageSubmitted: function (text) { /* Gets called when the user presses enter to send off a * message in a chat room. @@ -2903,15 +2918,17 @@ * Parameters: * (String) text - The message text. */ - var match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', '']; - var args = match[2].splitOnce(' '); + var match = text.replace(/^\s*/, "").match(/^\/(.*?)(?: (.*))?$/) || [false, '', ''], + args = match[2] && match[2].splitOnce(' ') || []; switch (match[1]) { case 'admin': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.setAffiliation( this.model.get('jid'), args[0], 'admin', args[1], undefined, this.onCommandError.bind(this)); break; case 'ban': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.setAffiliation( this.model.get('jid'), args[0], 'outcast', args[1], undefined, this.onCommandError.bind(this)); @@ -2920,6 +2937,7 @@ this.clearChatRoomMessages(); break; case 'deop': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.modifyRole( this.model.get('jid'), args[0], 'participant', args[1], undefined, this.onCommandError.bind(this)); @@ -2944,16 +2962,19 @@ ]); break; case 'kick': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.modifyRole( this.model.get('jid'), args[0], 'none', args[1], undefined, this.onCommandError.bind(this)); break; case 'mute': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.modifyRole( this.model.get('jid'), args[0], 'visitor', args[1], undefined, this.onCommandError.bind(this)); break; case 'member': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.setAffiliation( this.model.get('jid'), args[0], 'member', args[1], undefined, this.onCommandError.bind(this)); @@ -2966,16 +2987,19 @@ }).tree()); break; case 'owner': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.setAffiliation( this.model.get('jid'), args[0], 'owner', args[1], undefined, this.onCommandError.bind(this)); break; case 'op': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.modifyRole( this.model.get('jid'), args[0], 'moderator', args[1], undefined, this.onCommandError.bind(this)); break; case 'revoke': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.setAffiliation( this.model.get('jid'), args[0], 'none', args[1], undefined, this.onCommandError.bind(this)); @@ -2990,6 +3014,7 @@ ); break; case 'voice': + if (!this.validateRoleChangeCommand(match[1], args)) { break; } this.modifyRole( this.model.get('jid'), args[0], 'participant', args[1], undefined, this.onCommandError.bind(this)); diff --git a/docs/CHANGES.rst b/docs/CHANGES.rst index 5e8edadf4..7a86ab371 100644 --- a/docs/CHANGES.rst +++ b/docs/CHANGES.rst @@ -4,11 +4,12 @@ Changelog 0.9.6 (Unreleased) ------------------ +* Bugfix. Spinner doesn't disappear when scrolling up (when server doesn't support XEP-0313). [jcbrand] * #462 Fix MUC rooms with names containing special characters not working [1st8] * #468 Fix [object Object] being sometimes shown as status [1st8] +* #472 Fix "Cannot read property 'splitOnce' of undefined" when typing /clear in a chat room. [jcbrand] * #493 Roster wasn't being updated after a Roster push update [teseo, jcbrand] * #496 Bugfix. Pings weren't being sent out. [teseo, jcbrand] -* Bugfix. Spinner doesn't disappear when scrolling up (when server doesn't support XEP-0313). [jcbrand] 0.9.5 (2015-08-24) ------------------ diff --git a/spec/chatroom.js b/spec/chatroom.js index 7a68c3037..176fa099f 100644 --- a/spec/chatroom.js +++ b/spec/chatroom.js @@ -14,6 +14,13 @@ var Strophe = converse_api.env.Strophe; return describe("ChatRooms", function (mock, test_utils) { + beforeEach(function () { + runs(function () { + test_utils.closeAllChatBoxes(); + test_utils.clearBrowserStorage(); + }); + }); + describe("A Chat Room", function () { beforeEach(function () { runs(function () { @@ -478,6 +485,62 @@ }.bind(converse)); }.bind(converse)); }.bind(converse)); + + + describe("Each chat room can take special commands", function () { + beforeEach(function () { + runs(function () { + test_utils.closeAllChatBoxes(); + test_utils.clearBrowserStorage(); + }); + }); + + it("to clear messages", function () { + test_utils.openChatRoom('lounge', 'localhost', 'dummy'); + var view = converse.chatboxviews.get('lounge@localhost'), + chatroom = view.model, + $chat_content = view.$el.find('.chat-content'); + + spyOn(view, 'onChatRoomMessageSubmitted').andCallThrough(); + spyOn(view, 'clearChatRoomMessages'); + view.$el.find('.chat-textarea').text('/clear'); + view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13})); + expect(view.onChatRoomMessageSubmitted).toHaveBeenCalled(); + expect(view.clearChatRoomMessages).toHaveBeenCalled(); + + }); + + it("to ban a user", function () { + test_utils.openChatRoom('lounge', 'localhost', 'dummy'); + var view = converse.chatboxviews.get('lounge@localhost'), + chatroom = view.model, + $chat_content = view.$el.find('.chat-content'); + + spyOn(view, 'onChatRoomMessageSubmitted').andCallThrough(); + spyOn(view, 'setAffiliation').andCallThrough(); + spyOn(view, 'showStatusNotification').andCallThrough(); + spyOn(view, 'validateRoleChangeCommand').andCallThrough(); + view.$el.find('.chat-textarea').text('/ban'); + view.$el.find('textarea.chat-textarea').trigger($.Event('keypress', {keyCode: 13})); + expect(view.onChatRoomMessageSubmitted).toHaveBeenCalled(); + expect(view.validateRoleChangeCommand).toHaveBeenCalled(); + expect(view.showStatusNotification).toHaveBeenCalledWith( + "Error: the \"ban\" command takes two arguments, the user's nickname and optionally a reason.", + true + ); + expect(view.setAffiliation).not.toHaveBeenCalled(); + + // Call now with the correct amount of arguments. + // XXX: Calling onChatRoomMessageSubmitted directly, trying + // again via triggering Event doesn't work for some weird + // reason. + view.onChatRoomMessageSubmitted('/ban jid This is the reason'); + expect(view.validateRoleChangeCommand.callCount).toBe(2); + expect(view.showStatusNotification.callCount).toBe(1); + expect(view.setAffiliation).toHaveBeenCalled(); + }); + + }.bind(converse)); describe("When attempting to enter a chatroom", function () { beforeEach(function () {