From a83ddaace71688abc7f2b6a6dd1b821f2194e890 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Wed, 13 Apr 2016 20:43:51 +0200
Subject: Fix bug of /me commands not being shown as actions

Test-Information:

Added a test case that verifies this behavior. This test case
succeeded before the refactoring in 74e5131 and now succeeds
again.

Tested Swift UI 1-to-1 and MUC messages with /me commands.

Tested on OS X 10.11.4 with open-source clang.

Change-Id: I270a0b4e2ddc595919646bddcc5e1f27074c9e1f

diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 5b0bbd9..80f4167 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -17,7 +17,6 @@
 
 #include <Swiften/Avatars/AvatarManager.h>
 #include <Swiften/Base/Path.h>
-#include <Swiften/Base/String.h>
 #include <Swiften/Base/foreach.h>
 #include <Swiften/Base/format.h>
 #include <Swiften/Client/StanzaChannel.h>
@@ -209,12 +208,7 @@ bool ChatControllerBase::hasOpenWindow() const {
 
 ChatWindow::ChatMessage ChatControllerBase::buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction) {
     ChatWindow::ChatMessage chatMessage;
-    if (boost::starts_with(message, "/me ")) {
-        chatMessage = chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second);
-    }
-    else {
-        chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf);
-    }
+    chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf);
     chatMessage.setFullMessageHighlightAction(fullMessageHighlightAction);
     return chatMessage;
 }
diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp
index c204371..d639b06 100644
--- a/Swift/Controllers/Chat/ChatMessageParser.cpp
+++ b/Swift/Controllers/Chat/ChatMessageParser.cpp
@@ -13,6 +13,7 @@
 #include <boost/algorithm/string.hpp>
 
 #include <Swiften/Base/Regex.h>
+#include <Swiften/Base/String.h>
 #include <Swiften/Base/foreach.h>
 
 #include <SwifTools/Linkify.h>
@@ -28,6 +29,11 @@ namespace Swift {
     ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) {
         ChatWindow::ChatMessage parsedMessage;
         std::string remaining = body;
+        if (boost::starts_with(body, "/me ")) {
+           remaining = String::getSplittedAtFirst(body, ' ').second;
+           parsedMessage.setIsMeCommand(true);
+        }
+
         /* Parse one, URLs */
         while (!remaining.empty()) {
             bool found = false;
@@ -131,8 +137,7 @@ namespace Swift {
                     newMessage.append(part);
                 }
             }
-            parsedMessage = newMessage;
-
+            parsedMessage.setParts(newMessage.getParts());
         }
         return parsedMessage;
     }
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 90600dc..0a36180 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -80,6 +80,7 @@ class ChatsManagerTest : public CppUnit::TestFixture {
     CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
     CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting);
     CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds);
+    CPPUNIT_TEST(testChatControllerMeMessageHandling);
     CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -803,6 +804,20 @@ public:
         CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end());
     }
 
+    void testChatControllerMeMessageHandling() {
+        JID messageJID("testling@test.com/resource1");
+
+        MockChatWindow* window = new MockChatWindow();
+        mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+        std::shared_ptr<Message> message(new Message());
+        message->setFrom(messageJID);
+        std::string body("/me is feeling delighted.");
+        message->setBody(body);
+        manager_->handleIncomingMessage(message);
+        CPPUNIT_ASSERT_EQUAL(std::string("is feeling delighted."), window->lastAddedActionBody_);
+    }
+
 private:
     std::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
         std::shared_ptr<Message> message = std::make_shared<Message>();
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 2636bda..3aa1c7e 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -45,9 +45,11 @@ namespace Swift {
             class ChatMessage {
                 public:
                     ChatMessage() {}
+
                     ChatMessage(const std::string& text) {
                         append(std::make_shared<ChatTextMessagePart>(text));
                     }
+
                     void append(const std::shared_ptr<ChatMessagePart>& part) {
                         parts_.push_back(part);
                     }
@@ -56,6 +58,10 @@ namespace Swift {
                         return parts_;
                     }
 
+                    void setParts(const std::vector<std::shared_ptr<ChatMessagePart> >& parts) {
+                        parts_ = parts;
+                    }
+
                     void setFullMessageHighlightAction(const HighlightAction& action) {
                         fullMessageHighlightAction_ = action;
                     }
@@ -65,21 +71,17 @@ namespace Swift {
                     }
 
                     bool isMeCommand() const {
-                        bool isMeCommand = false;
-                        if (!parts_.empty()) {
-                            std::shared_ptr<ChatTextMessagePart> textPart = std::dynamic_pointer_cast<ChatTextMessagePart>(parts_[0]);
-                            if (textPart) {
-                                if (boost::starts_with(textPart->text, "/me ")) {
-                                    isMeCommand = true;
-                                }
-                            }
-                        }
-                        return isMeCommand;
+                        return isMeCommand_;
+                    }
+
+                    void setIsMeCommand(bool isMeCommand) {
+                        isMeCommand_ = isMeCommand;
                     }
 
                 private:
                     std::vector<std::shared_ptr<ChatMessagePart> > parts_;
                     HighlightAction fullMessageHighlightAction_;
+                    bool isMeCommand_ = false;
             };
 
             class ChatTextMessagePart : public ChatMessagePart {
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 9a97994..1430f4f 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -23,7 +23,10 @@ namespace Swift {
                 return "id";
             }
 
-            virtual std::string addAction(const ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {return "id";}
+            virtual std::string addAction(const ChatMessage& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {
+                lastAddedActionBody_ =bodyFromMessage(message);
+                return "id";
+            }
 
             virtual std::string addSystemMessage(const ChatMessage& message, Direction /*direction*/) {
                 lastAddedSystemMessage_ = message;
@@ -102,6 +105,7 @@ namespace Swift {
 
             std::string name_;
             std::string lastMessageBody_;
+            std::string lastAddedActionBody_;
             ChatMessage lastAddedPresence_;
             ChatMessage lastReplacedMessage_;
             ChatMessage lastAddedSystemMessage_;
-- 
cgit v0.10.2-6-g49f6