Fix #98 - Leave the room internally when disconnecting user from room because of error.

This commit is contained in:
Jan Kaluza 2016-01-20 07:36:05 +01:00
parent f6cb536eb0
commit 17fe52b61f
4 changed files with 47 additions and 13 deletions

View file

@ -138,6 +138,8 @@ class User {
m_reconnectLimit = limit;
}
void leaveRoom(const std::string &room);
boost::signal<void ()> onReadyToConnect;
boost::signal<void (Swift::Presence::ref presence)> onPresenceChanged;
boost::signal<void (Swift::Presence::ref presence)> onRawPresenceReceived;

View file

@ -363,6 +363,13 @@ void Conversation::handleParticipantChanged(const std::string &nick, Conversatio
m_conversationManager->getComponent()->getFrontend()->sendMessage(m_subject);
m_subject.reset();
}
// We send error presences only to inform user that he is disconnected
// from the room. This code must be extended in case we start sending error
// presences in other situations.
if (presence->getType() == Swift::Presence::Error) {
m_conversationManager->getUser()->leaveRoom(m_legacyName);
}
}
}

View file

@ -151,6 +151,23 @@ void User::setCacheMessages(bool cacheMessages) {
m_cacheMessages = cacheMessages;
}
void User::leaveRoom(const std::string &room) {
onRoomLeft(room);
BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
if (Buddy::JIDToLegacyName(p->getTo()) == room) {
m_joinedRooms.remove(p);
break;
}
}
Conversation *conv = m_conversationManager->getConversation(room);
if (conv) {
m_conversationManager->removeConversation(conv);
delete conv;
}
}
void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString());
if (!m_connected) {
@ -196,19 +213,7 @@ void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) {
if (getUserSetting("stay_connected") != "1") {
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
onRawPresenceReceived(presence);
onRoomLeft(room);
BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) {
if (p->getTo() == presence->getTo()) {
m_joinedRooms.remove(p);
break;
}
}
if (conv) {
m_conversationManager->removeConversation(conv);
delete conv;
}
leaveRoom(room);
}
return;

View file

@ -29,6 +29,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_TEST(handleDisconnected);
CPPUNIT_TEST(handleDisconnectedReconnect);
CPPUNIT_TEST(joinRoomHandleDisconnectedRejoin);
CPPUNIT_TEST(joinRoomAfterFlagNotAuthorized);
CPPUNIT_TEST_SUITE_END();
public:
@ -138,6 +139,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
// simulate that backend joined the room
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "room", true);
conv->addJID("user@localhost/resource");
conv->setNickname("hanzz");
user->getConversationManager()->addConversation(conv);
received.clear();
@ -452,6 +454,24 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
}
void joinRoomAfterFlagNotAuthorized() {
User *user = userManager->getUser("user@localhost");
handlePresenceJoinRoom();
Conversation *conv = user->getConversationManager()->getConversation("room");
conv->handleParticipantChanged("hanzz", Conversation::PARTICIPANT_FLAG_NOT_AUTHORIZED, Swift::StatusShow::Away, "my status message");
loop->processEvents();
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received[0])));
CPPUNIT_ASSERT_EQUAL(Swift::Presence::Error, dynamic_cast<Swift::Presence *>(getStanza(received[0]))->getType());
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::ErrorPayload>());
CPPUNIT_ASSERT_EQUAL(Swift::ErrorPayload::NotAuthorized, getStanza(received[0])->getPayload<Swift::ErrorPayload>()->getCondition());
received.clear();
handlePresenceJoinRoom();
}
};
CPPUNIT_TEST_SUITE_REGISTRATION (UserTest);