From 3861c418f95555a623d3e8005c75da9b9bbcd1e1 Mon Sep 17 00:00:00 2001
From: Joanna Hulboj <joanna.hulboj@isode.com>
Date: Wed, 15 Feb 2017 16:21:26 +0000
Subject: Change the logic of displaying chat room subject

Test-Information:

Run Swift and join any MUC room, on join there is no information
displayed regarding room subject.

Choose "Change subject", the following information is displayed
in the chat window: "The room subject
has been removed" after the subject was removed, or "The room subject is
now: some subject" after the room subject was set to "some subject".

Run Swift join any MUC room, disconnect from server (using another Swift
client change subject to "Test") after reconnecting the following
information is displayed in chat window: "The room subject is
now: Test"

Change-Id: Ice901697a6a381464d694147b17830b4e62c8198

diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 9d1459d..df54d73 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -104,6 +104,8 @@ MUCController::MUCController (
     shouldJoinOnReconnect_ = true;
     doneGettingHistory_ = false;
     xmppRoster_ = xmppRoster;
+    subject_ = "";
+    isInitialJoin_ = true;
 
     roster_ = std::unique_ptr<Roster>(new Roster(false, true));
     rosterVCardProvider_ = new RosterVCardProvider(roster_.get(), vcardManager, JID::WithResource);
@@ -559,9 +561,13 @@ void MUCController::preHandleIncomingMessage(std::shared_ptr<MessageEvent> messa
     joined_ = true;
 
     if (message->hasSubject() && !message->getPayload<Body>() && !message->getPayload<Thread>()) {
-        chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject())), ChatWindow::DefaultDirection);
+        if (!isInitialJoin_) {
+            displaySubjectIfChanged(message->getSubject());
+        }
+        isInitialJoin_ = false;
         chatWindow_->setSubject(message->getSubject());
         doneGettingHistory_ = true;
+        subject_ = message->getSubject();
     }
 
     if (!doneGettingHistory_ && !message->getPayload<Delay>()) {
@@ -1216,4 +1222,16 @@ void MUCController::updateChatWindowBookmarkStatus(const boost::optional<MUCBook
     }
 }
 
+void MUCController::displaySubjectIfChanged(const std::string& subject) {
+    if (subject_ != subject) {
+        if (!subject.empty()) {
+            chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % subject)), ChatWindow::DefaultDirection);
+        }
+        else {
+            chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject has been removed")))), ChatWindow::DefaultDirection);
+        }
+        subject_ = subject;
+    }
+}
+
 }
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 7aff627..7ec2eb4 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -144,6 +144,8 @@ namespace Swift {
             void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
             void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark);
 
+            void displaySubjectIfChanged(const std::string& sucject);
+
         private:
             MUC::ref muc_;
             std::string nick_;
@@ -178,6 +180,9 @@ namespace Swift {
             MUCBookmarkManager* mucBookmarkManager_;
             boost::signals2::scoped_connection mucBookmarkManagerBookmarkAddedConnection_;
             boost::signals2::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_;
+
+            std::string subject_;
+            bool isInitialJoin_;
     };
 }
 
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index 59dcd77..dad021f 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -64,6 +64,7 @@ class MUCControllerTest : public CppUnit::TestFixture {
     CPPUNIT_TEST(testSubjectChangeIncorrectC);
     CPPUNIT_TEST(testHandleOccupantNicknameChanged);
     CPPUNIT_TEST(testHandleOccupantNicknameChangedRoster);
+    CPPUNIT_TEST(testHandleChangeSubjectRequest);
     CPPUNIT_TEST_SUITE_END();
 
 public:
@@ -135,6 +136,27 @@ public:
         stanzaChannel_->onPresenceReceived(presence);
     }
 
+    void joinCompleted() {
+        std::string messageBody("test message");
+        window_->onSendMessageRequest(messageBody, false);
+        std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+        Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+        CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+        CPPUNIT_ASSERT(message);
+        CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+
+        {
+            Message::ref message = std::make_shared<Message>();
+            message->setType(Message::Groupchat);
+            message->setTo(self_);
+            message->setFrom(mucJID_.withResource("SomeNickname"));
+            message->setID(iqChannel_->getNewIQID());
+            message->setSubject("Initial");
+
+            controller_->handleIncomingMessage(std::make_shared<MessageEvent>(message));
+        }
+    }
+
     void testAddressedToSelf() {
         finishJoin();
         Message::ref message(new Message());
@@ -404,13 +426,7 @@ public:
     }
 
     void testSubjectChangeCorrect() {
-        std::string messageBody("test message");
-        window_->onSendMessageRequest(messageBody, false);
-        std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
-        Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
-        CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
-        CPPUNIT_ASSERT(message);
-        CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+        joinCompleted();
 
         {
             Message::ref message = std::make_shared<Message>();
@@ -429,13 +445,7 @@ public:
      * Test that message stanzas with subject element and non-empty body element do not cause a subject change.
      */
     void testSubjectChangeIncorrectA() {
-        std::string messageBody("test message");
-        window_->onSendMessageRequest(messageBody, false);
-        std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
-        Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
-        CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
-        CPPUNIT_ASSERT(message);
-        CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+        joinCompleted();
 
         {
             Message::ref message = std::make_shared<Message>();
@@ -455,13 +465,7 @@ public:
      * Test that message stanzas with subject element and thread element do not cause a subject change.
      */
     void testSubjectChangeIncorrectB() {
-        std::string messageBody("test message");
-        window_->onSendMessageRequest(messageBody, false);
-        std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
-        Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
-        CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
-        CPPUNIT_ASSERT(message);
-        CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+        joinCompleted();
 
         {
             Message::ref message = std::make_shared<Message>();
@@ -481,13 +485,7 @@ public:
      * Test that message stanzas with subject element and empty body element do not cause a subject change.
      */
     void testSubjectChangeIncorrectC() {
-        std::string messageBody("test message");
-        window_->onSendMessageRequest(messageBody, false);
-        std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
-        Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
-        CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
-        CPPUNIT_ASSERT(message);
-        CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+        joinCompleted();
 
         {
             Message::ref message = std::make_shared<Message>();
@@ -575,6 +573,13 @@ public:
         }
     }
 
+    void testHandleChangeSubjectRequest() {
+        std::string testStr("New Subject");
+        CPPUNIT_ASSERT_EQUAL(std::string(""), muc_->newSubjectSet_);
+        window_->onChangeSubjectRequest(testStr);
+        CPPUNIT_ASSERT_EQUAL(testStr, muc_->newSubjectSet_);
+    }
+
 private:
     JID self_;
     JID mucJID_;
diff --git a/Swiften/MUC/UnitTest/MockMUC.cpp b/Swiften/MUC/UnitTest/MockMUC.cpp
index 93e7d0b..d9bf348 100644
--- a/Swiften/MUC/UnitTest/MockMUC.cpp
+++ b/Swiften/MUC/UnitTest/MockMUC.cpp
@@ -10,6 +10,7 @@ namespace Swift {
 
 MockMUC::MockMUC(const JID &muc)
 : ownMUCJID(muc)
+, newSubjectSet_("")
 {
 }
 
@@ -47,5 +48,8 @@ void MockMUC::changeOccupantRole(const JID &jid, MUCOccupant::Role newRole) {
         onOccupantRoleChanged(i->first, i->second, old.getRole());
     }
 }
+void MockMUC::changeSubject(const std::string& newSubject) {
+    newSubjectSet_ = newSubject;
+}
 
 }
diff --git a/Swiften/MUC/UnitTest/MockMUC.h b/Swiften/MUC/UnitTest/MockMUC.h
index becfa72..4c5ce8d 100644
--- a/Swiften/MUC/UnitTest/MockMUC.h
+++ b/Swiften/MUC/UnitTest/MockMUC.h
@@ -72,7 +72,7 @@ namespace Swift {
             virtual void changeOccupantRole(const JID&, MUCOccupant::Role);
             virtual void requestAffiliationList(MUCOccupant::Affiliation) {}
             virtual void changeAffiliation(const JID&, MUCOccupant::Affiliation);
-            virtual void changeSubject(const std::string&) {}
+            virtual void changeSubject(const std::string&);
             virtual void requestConfigurationForm() {}
             virtual void configureRoom(Form::ref) {}
             virtual void cancelConfigureRoom() {}
@@ -94,5 +94,8 @@ namespace Swift {
         private:
             JID ownMUCJID;
             std::map<std::string, MUCOccupant> occupants_;
+
+        public:
+            std::string newSubjectSet_;
     };
 }
-- 
cgit v0.10.2-6-g49f6