diff --git a/include/transport/conversationmanager.h b/include/transport/conversationmanager.h index 44c81888..016914c8 100644 --- a/include/transport/conversationmanager.h +++ b/include/transport/conversationmanager.h @@ -70,6 +70,7 @@ class ConversationManager { void removeConversation(Conversation *conv); void resetResources(); + void removeJID(const Swift::JID &jid); private: void handleMessageReceived(Swift::Message::ref message); diff --git a/src/conversationmanager.cpp b/src/conversationmanager.cpp index 2089238e..4fc23afc 100644 --- a/src/conversationmanager.cpp +++ b/src/conversationmanager.cpp @@ -89,6 +89,12 @@ void ConversationManager::resetResources() { } } +void ConversationManager::removeJID(const Swift::JID &jid) { + for (std::map::const_iterator it = m_convs.begin(); it != m_convs.end(); it++) { + (*it).second->removeJID(jid); + } +} + void ConversationManager::handleMessageReceived(Swift::Message::ref message) { // std::string name = message->getTo().getUnescapedNode(); // if (name.find_last_of("%") != std::string::npos) { // OK when commented diff --git a/src/tests/user.cpp b/src/tests/user.cpp index 5755ad0d..bbafedbb 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -28,6 +28,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST(handlePresenceJoinRoomTwoResources); CPPUNIT_TEST(handlePresenceLeaveRoom); CPPUNIT_TEST(handlePresenceLeaveRoomTwoResources); + CPPUNIT_TEST(handlePresenceLeaveRoomTwoResourcesOneDisconnects); CPPUNIT_TEST(leaveJoinedRoom); CPPUNIT_TEST(handleDisconnected); CPPUNIT_TEST(handleDisconnectedReconnect); @@ -253,6 +254,29 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); } + void handlePresenceLeaveRoomTwoResourcesOneDisconnects() { + handlePresenceJoinRoomTwoResources(); + received.clear(); + User *user = userManager->getUser("user@localhost"); + + // User is still connected from resource2, so he should not leave the room + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("localhost/hanzz"); + response->setFrom("user@localhost/resource"); + response->setType(Swift::Presence::Unavailable); + injectPresence(response); + loop->processEvents(); + + + CPPUNIT_ASSERT_EQUAL(std::string(""), room); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); + + Conversation *conv = user->getConversationManager()->getConversation("#room"); + CPPUNIT_ASSERT_EQUAL(1, (int) conv->getJIDs().size()); + CPPUNIT_ASSERT_EQUAL(Swift::JID("user@localhost/resource2"), conv->getJIDs().front()); + } + void leaveJoinedRoom() { User *user = userManager->getUser("user@localhost"); handlePresenceJoinRoom(); diff --git a/src/user.cpp b/src/user.cpp index ac37f799..f791b992 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -263,6 +263,10 @@ void User::handlePresence(Swift::Presence::ref presence) { } return; } + + if (presence->getType() == Swift::Presence::Unavailable) { + m_conversationManager->removeJID(presence->getFrom()); + } // User wants to disconnect this resource