diff options
-rw-r--r-- | Swift/Controllers/Chat/ChatController.cpp | 20 | ||||
-rw-r--r-- | Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp | 31 | ||||
-rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 12 |
3 files changed, 56 insertions, 7 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 503a050..e2751f7 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -466,10 +466,22 @@ std::string ChatController::getStatusChangeString(boost::shared_ptr<Presence> pr void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence) { bool relevantPresence = false; - if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) { - // Presence matches ChatController JID. - newPresence = presenceOracle_->getAccountPresence(toJID_); - relevantPresence = true; + if (isInMUC_) { + // For MUC participants we only have a single presence to choose one and + // even for multi-session nicknames multiple resources are not distinguishable + // to other participants. + if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) { + relevantPresence = true; + } + } + else { + // For standard chats we retrieve the account presence from the PresenceOracle, + // as there can be multiple presences to choose from. + if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) { + // Presence matches ChatController JID. + newPresence = presenceOracle_->getAccountPresence(toJID_); + relevantPresence = true; + } } if (!relevantPresence) { diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index 281783e..5f89f62 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -73,6 +73,7 @@ class ChatsManagerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom); CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt); CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive); + CPPUNIT_TEST(testChatControllerPMPresenceHandling); CPPUNIT_TEST_SUITE_END(); public: @@ -642,6 +643,36 @@ public: CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>()); } + void testChatControllerPMPresenceHandling() { + JID participantA = JID("test@rooms.test.com/participantA"); + JID participantB = JID("test@rooms.test.com/participantB"); + + mucRegistry_->addMUC("test@rooms.test.com"); + + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(participantA)))); + + Presence::ref presence = Presence::create(); + presence->setFrom(participantA); + presence->setShow(StatusShow::Online); + stanzaChannel_->onPresenceReceived(presence); + CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_)); + + presence = Presence::create(); + presence->setFrom(participantB); + presence->setShow(StatusShow::Away); + stanzaChannel_->onPresenceReceived(presence); + + presence = Presence::create(); + presence->setFrom(participantA); + presence->setShow(StatusShow::None); + presence->setType(Presence::Unavailable); + stanzaChannel_->onPresenceReceived(presence); + CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_)); + } + void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) { JID messageJID("testling@test.com/resource1"); xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from); diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index c906bfd..ddb7e3e 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -29,12 +29,16 @@ namespace Swift { return "id"; } - virtual void addPresenceMessage(const ChatMessage& /*message*/, Direction /*direction*/) {} + virtual void addPresenceMessage(const ChatMessage& message, Direction /*direction*/) { + lastAddedPresence_ = message; + } virtual void addErrorMessage(const ChatMessage& /*message*/) {} virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {} virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {} - virtual void replaceLastMessage(const ChatMessage& /*message*/, const TimestampBehaviour /*timestampBehaviour*/) {} + virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour /*timestampBehaviour*/) { + lastReplacedMessage_ = message; + } virtual void replaceSystemMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const TimestampBehaviour /*timestampBehaviour*/) {} // File transfer related stuff @@ -82,7 +86,7 @@ namespace Swift { virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {} virtual void setBookmarkState(RoomBookmarkState) {} - std::string bodyFromMessage(const ChatMessage& message) { + static std::string bodyFromMessage(const ChatMessage& message) { boost::shared_ptr<ChatTextMessagePart> text; foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) { if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) { @@ -94,6 +98,8 @@ namespace Swift { std::string name_; std::string lastMessageBody_; + ChatMessage lastAddedPresence_; + ChatMessage lastReplacedMessage_; std::vector<SecurityLabelsCatalog::Item> labels_; bool labelsEnabled_; SecurityLabelsCatalog::Item label_; |