void SubscriptionManager::handleIncomingPresence(Presence::ref presence) { JID bareJID(presence->getFrom().toBare()); if (presence->getType() == Presence::Subscribe) { onPresenceSubscriptionRequest(bareJID, presence->getStatus(), presence); } else if (presence->getType() == Presence::Unsubscribe) { onPresenceSubscriptionRevoked(bareJID, presence->getStatus()); } }
void testUnavailablePresence() { std::vector<std::string> groups; groups.push_back("testGroup1"); JID from("*****@*****.**"); xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); Presence::ref lowPresence(new Presence()); lowPresence->setFrom(withResource(from, "bob")); lowPresence->setPriority(2); lowPresence->setShow(StatusShow::Away); lowPresence->setStatus("Not here"); Presence::ref lowPresenceOffline(new Presence()); lowPresenceOffline->setFrom(withResource(from, "bob")); lowPresenceOffline->setStatus("Signing out"); lowPresenceOffline->setType(Presence::Unavailable); Presence::ref highPresence(new Presence()); highPresence->setFrom(withResource(from, "bert")); highPresence->setPriority(10); highPresence->setStatus("So totally here"); Presence::ref highPresenceOffline(new Presence()); highPresenceOffline->setFrom(withResource(from, "bert")); highPresenceOffline->setType(Presence::Unavailable); stanzaChannel_->onPresenceReceived(lowPresence); Presence::ref accountPresence = presenceOracle_->getAccountPresence(from); CPPUNIT_ASSERT_EQUAL(StatusShow::Away, accountPresence->getShow()); stanzaChannel_->onPresenceReceived(highPresence); accountPresence = presenceOracle_->getAccountPresence(from); CPPUNIT_ASSERT_EQUAL(StatusShow::Online, accountPresence->getShow()); stanzaChannel_->onPresenceReceived(highPresenceOffline); // After this, the roster should show the low presence. ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); CPPUNIT_ASSERT(item); Presence::ref low = presenceOracle_->getAccountPresence(from); CPPUNIT_ASSERT_EQUAL(Presence::Available, low->getType()); CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), low->getStatus()); CPPUNIT_ASSERT_EQUAL(lowPresence->getShow(), item->getStatusShow()); CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), item->getStatusText()); stanzaChannel_->onPresenceReceived(lowPresenceOffline); item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); CPPUNIT_ASSERT(item); /* A verification that if the test fails, it's the RosterController, not the PresenceOracle. */ low = presenceOracle_->getHighestPriorityPresence(from); CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, low->getType()); CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), low->getStatus()); CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow()); CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText()); }
void PresenceOracle::handleIncomingPresence(Presence::ref presence) { // ignore presences for some contact, we're checking only presences for the transport itself here. // filter out login/logout presence spam if (!presence->getTo().getNode().empty()) return; JID bareJID(presence->getFrom().toBare()); if (presence->getType() == Presence::Subscribe || presence->getType() == Presence::Subscribed) { } else { Presence::ref passedPresence = presence; if (presence->getType() == Presence::Unsubscribe || presence->getType() == Presence::Unsubscribed) { /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ passedPresence = Presence::ref(new Presence()); passedPresence->setType(Presence::Unavailable); passedPresence->setFrom(bareJID); passedPresence->setStatus(presence->getStatus()); } std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID]; if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { /* Have a bare-JID only presence of offline */ jidMap.clear(); } else if (passedPresence->getType() == Presence::Available) { /* Don't have a bare-JID only offline presence once there are available presences */ jidMap.erase(bareJID); } if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) { jidMap.erase(passedPresence->getFrom()); } else { jidMap[passedPresence->getFrom()] = passedPresence; } entries_[bareJID] = jidMap; onPresenceChange(passedPresence); } }
void PresenceOracle::handleIncomingPresence(Presence::ref presence) { JID bareJID(presence->getFrom().toBare()); if (presence->getType() == Presence::Subscribe) { } else { Presence::ref passedPresence = presence; if (presence->getType() == Presence::Unsubscribe) { /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ passedPresence = Presence::ref(new Presence()); passedPresence->setType(Presence::Unavailable); passedPresence->setFrom(bareJID); passedPresence->setStatus(presence->getStatus()); } std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID]; if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { /* Have a bare-JID only presence of offline */ jidMap.clear(); } else if (passedPresence->getType() == Presence::Available) { /* Don't have a bare-JID only offline presence once there are available presences */ jidMap.erase(bareJID); } if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) { jidMap.erase(passedPresence->getFrom()); } else { jidMap[passedPresence->getFrom()] = passedPresence; } entries_[bareJID] = jidMap; onPresenceChange(passedPresence); } }