Send participants to second resource when it joins the room
This commit is contained in:
parent
88607aff3c
commit
1055c577d2
5 changed files with 127 additions and 2 deletions
|
@ -34,6 +34,12 @@ class ConversationManager;
|
|||
/// Represents one XMPP-Legacy network conversation.
|
||||
class Conversation {
|
||||
public:
|
||||
typedef struct _Participant {
|
||||
int flag;
|
||||
int status;
|
||||
std::string statusMessage;
|
||||
} Participant;
|
||||
|
||||
/// Type of participants in MUC rooms.
|
||||
enum ParticipantFlag {None, Moderator};
|
||||
|
||||
|
@ -128,6 +134,11 @@ class Conversation {
|
|||
|
||||
void destroyRoom();
|
||||
|
||||
void sendParticipants(const Swift::JID &to);
|
||||
|
||||
private:
|
||||
Swift::Presence::ref generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname = "");
|
||||
|
||||
private:
|
||||
ConversationManager *m_conversationManager;
|
||||
std::string m_legacyName;
|
||||
|
@ -136,6 +147,7 @@ class Conversation {
|
|||
bool m_muc;
|
||||
Swift::JID m_jid;
|
||||
std::list<Swift::JID> m_jids;
|
||||
std::map<std::string, Participant> m_participants;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -123,7 +123,15 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
|
|||
}
|
||||
}
|
||||
|
||||
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
|
||||
void Conversation::sendParticipants(const Swift::JID &to) {
|
||||
for (std::map<std::string, Participant>::iterator it = m_participants.begin(); it != m_participants.end(); it++) {
|
||||
Swift::Presence::ref presence = generatePresence(it->first, it->second.flag, it->second.status, it->second.statusMessage, "");
|
||||
presence->setTo(to);
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
}
|
||||
|
||||
Swift::Presence::ref Conversation::generatePresence(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
|
||||
std::string nickname = nick;
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
std::string legacyName = m_legacyName;
|
||||
|
@ -173,8 +181,25 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i
|
|||
}
|
||||
|
||||
p->addItem(item);
|
||||
|
||||
presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
|
||||
return presence;
|
||||
}
|
||||
|
||||
void Conversation::handleParticipantChanged(const std::string &nick, int flag, int status, const std::string &statusMessage, const std::string &newname) {
|
||||
Swift::Presence::ref presence = generatePresence(nick, flag, status, statusMessage, newname);
|
||||
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
m_participants.erase(nick);
|
||||
}
|
||||
else {
|
||||
Participant p;
|
||||
p.flag = flag;
|
||||
p.status = status;
|
||||
p.statusMessage = statusMessage;
|
||||
m_participants[nick] = p;
|
||||
}
|
||||
|
||||
|
||||
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
|
||||
presence->setTo(jid);
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
|
|
|
@ -25,8 +25,10 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
CPPUNIT_TEST_SUITE(ConversationManagerTest);
|
||||
CPPUNIT_TEST(handleNormalMessages);
|
||||
CPPUNIT_TEST(handleGroupchatMessages);
|
||||
CPPUNIT_TEST(handleGroupchatMessagesTwoResources);
|
||||
CPPUNIT_TEST(handleChatstateMessages);
|
||||
CPPUNIT_TEST(handleParticipantChanged);
|
||||
CPPUNIT_TEST(handleParticipantChangedTwoResources);
|
||||
CPPUNIT_TEST(handlePMFromXMPP);
|
||||
CPPUNIT_TEST(handleGroupchatRemoved);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
@ -191,6 +193,48 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
|
||||
}
|
||||
|
||||
void handleGroupchatMessagesTwoResources() {
|
||||
connectSecondResource();
|
||||
received2.clear();
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
user->getConversationManager()->addConversation(conv);
|
||||
conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname("nickname");
|
||||
conv->addJID("user@localhost/resource");
|
||||
conv->addJID("user@localhost/resource2");
|
||||
|
||||
// reset resources should not touch this resource
|
||||
user->getConversationManager()->resetResources();
|
||||
|
||||
boost::shared_ptr<Swift::Message> msg(new Swift::Message());
|
||||
msg->setBody("hi there!");
|
||||
|
||||
// Forward it
|
||||
conv->handleMessage(msg, "anotheruser");
|
||||
|
||||
loop->processEvents();
|
||||
CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Message *>(getStanza(received2[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("hi there!"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getBody());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Message *>(getStanza(received2[0]))->getFrom().toString());
|
||||
|
||||
received.clear();
|
||||
|
||||
// send response
|
||||
msg->setFrom("user@localhost/resource2");
|
||||
msg->setTo("#room@localhost");
|
||||
msg->setBody("response!");
|
||||
msg->setType(Swift::Message::Groupchat);
|
||||
injectMessage(msg);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
CPPUNIT_ASSERT(m_msg);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("response!"), m_msg->getBody());
|
||||
}
|
||||
|
||||
void handleParticipantChanged() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
|
@ -246,6 +290,31 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
CPPUNIT_ASSERT_EQUAL(303, getStanza(received[0])->getPayload<Swift::MUCUserPayload>()->getStatusCodes()[0].code);
|
||||
}
|
||||
|
||||
void handleParticipantChangedTwoResources() {
|
||||
connectSecondResource();
|
||||
received2.clear();
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
|
||||
conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname("nickname");
|
||||
conv->addJID("user@localhost/resource");
|
||||
conv->addJID("user@localhost/resource2");
|
||||
|
||||
// normal presence
|
||||
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(1, (int) received2.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getShow());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[0]))->getFrom().toString());
|
||||
CPPUNIT_ASSERT(getStanza(received2[0])->getPayload<Swift::MUCUserPayload>());
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[0])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
|
||||
}
|
||||
|
||||
void handlePMFromXMPP() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
|
|
|
@ -159,7 +159,15 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
|
||||
void handlePresenceJoinRoomTwoResources() {
|
||||
handlePresenceJoinRoom();
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
|
||||
// Add 1 participant
|
||||
Conversation *conv = user->getConversationManager()->getConversation("#room");
|
||||
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
|
||||
|
||||
// Connect 2nd resource
|
||||
connectSecondResource();
|
||||
received2.clear();
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource2");
|
||||
|
@ -173,6 +181,16 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
|
||||
dumpReceived();
|
||||
CPPUNIT_ASSERT_EQUAL(2, (int) received2.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::Presence *>(getStanza(received2[1])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::StatusShow::Away, dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getShow());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("user@localhost/resource2"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getTo().toString());
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room@localhost/anotheruser"), dynamic_cast<Swift::Presence *>(getStanza(received2[1]))->getFrom().toString());
|
||||
CPPUNIT_ASSERT(getStanza(received2[1])->getPayload<Swift::MUCUserPayload>());
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Member, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].affiliation);
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::MUCOccupant::Participant, *getStanza(received2[1])->getPayload<Swift::MUCUserPayload>()->getItems()[0].role);
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoom() {
|
||||
|
|
|
@ -249,6 +249,7 @@ void User::handlePresence(Swift::Presence::ref presence) {
|
|||
}
|
||||
else {
|
||||
conv->addJID(presence->getFrom());
|
||||
conv->sendParticipants(presence->getFrom());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue