summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat')
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp8
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp68
2 files changed, 75 insertions, 1 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 8fa98f6..545eab5 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -539,8 +539,14 @@ void MUCController::preHandleIncomingMessage(std::shared_ptr<MessageEvent> messa
if (messageEvent->getStanza()->getType() == Message::Groupchat) {
lastActivity_ = boost::posix_time::microsec_clock::universal_time();
}
- clearPresenceQueue();
std::shared_ptr<Message> message = messageEvent->getStanza();
+
+ // This avoids clearing join/leave queue for chat state notification messages
+ // which are not readable (e.g. have no body content).
+ if (!(!messageEvent->isReadable() && message->getPayload<ChatState>())) {
+ clearPresenceQueue();
+ }
+
if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>() && messageEvent->isReadable()) {
chatWindow_->flash();
}
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 00df3da..1958408 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -116,6 +116,7 @@ class ChatsManagerTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
CPPUNIT_TEST(testPresenceChangeDoesNotReplaceMUCInvite);
+ CPPUNIT_TEST(testNotSplittingMUCPresenceJoinLeaveLinesOnChatStateNotifications);
// MUC PM Tests
CPPUNIT_TEST(testChatControllerPMPresenceHandling);
@@ -1095,6 +1096,73 @@ public:
CPPUNIT_ASSERT_EQUAL(std::string("testling@test.com has gone offline."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
}
+ void testNotSplittingMUCPresenceJoinLeaveLinesOnChatStateNotifications() {
+ JID mucJID("mucroom@rooms.test.com");
+ std::string nickname = "toodles";
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(mucJID, boost::optional<std::string>(), nickname));
+
+ auto genRemoteMUCPresence = [=]() {
+ auto presence = Presence::create();
+ presence->setFrom(mucJID.withResource(nickname));
+ presence->setTo(jid_);
+ return presence;
+ };
+
+ {
+ auto presence = genRemoteMUCPresence();
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ userPayload->addStatusCode(110);
+ userPayload->addItem(MUCItem(MUCOccupant::Owner, jid_, MUCOccupant::Moderator));
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+
+ {
+ auto presence = genRemoteMUCPresence();
+ presence->setFrom(mucJID.withResource("someDifferentNickname"));
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string("someDifferentNickname has entered the room."), window->bodyFromMessage(window->lastAddedPresence_));
+ CPPUNIT_ASSERT_EQUAL(std::string(), window->bodyFromMessage(window->lastReplacedMessage_));
+ window->resetLastMessages();
+
+ {
+ auto presence = genRemoteMUCPresence();
+ presence->setFrom(mucJID.withResource("Romeo"));
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string(), window->bodyFromMessage(window->lastAddedPresence_));
+ CPPUNIT_ASSERT_EQUAL(std::string("someDifferentNickname and Romeo have entered the room"), window->bodyFromMessage(window->lastReplacedMessage_));
+ window->resetLastMessages();
+
+ {
+ auto message = std::make_shared<Message>();
+ message->setFrom(mucJID.withResource("Romeo"));
+ message->setTo(mucJID);
+ message->setType(Message::Groupchat);
+ message->addPayload(std::make_shared<ChatState>(ChatState::Composing));
+ manager_->handleIncomingMessage(message);
+ }
+
+ {
+ auto presence = genRemoteMUCPresence();
+ presence->setFrom(mucJID.withResource("Juliet"));
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string(), window->bodyFromMessage(window->lastAddedPresence_));
+ CPPUNIT_ASSERT_EQUAL(std::string("someDifferentNickname, Romeo and Juliet have entered the room"), window->bodyFromMessage(window->lastReplacedMessage_));
+ }
+
template <typename CarbonsType>
Message::ref createCarbonsMessage(std::shared_ptr<CarbonsType> carbons, std::shared_ptr<Message> forwardedMessage) {
auto messageWrapper = std::make_shared<Message>();