diff options
Diffstat (limited to 'Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp')
-rw-r--r-- | Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp new file mode 100644 index 0000000..0a498cf --- /dev/null +++ b/Swiften/Disco/UnitTest/EntityCapsManagerTest.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <vector> +#include <boost/bind.hpp> + +#include "Swiften/Disco/EntityCapsManager.h" +#include "Swiften/Disco/CapsProvider.h" +#include "Swiften/Elements/CapsInfo.h" +#include "Swiften/Client/DummyStanzaChannel.h" +#include "Swiften/Disco/CapsInfoGenerator.h" + +using namespace Swift; + +class EntityCapsManagerTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(EntityCapsManagerTest); + CPPUNIT_TEST(testReceiveKnownHash); + CPPUNIT_TEST(testReceiveKnownHashTwiceDoesNotTriggerChange); + CPPUNIT_TEST(testReceiveUnknownHashDoesNotTriggerChange); + CPPUNIT_TEST(testReceiveUnknownHashAfterKnownHashTriggersChangeAndClearsCaps); + CPPUNIT_TEST(testReceiveUnavailablePresenceAfterKnownHashTriggersChangeAndClearsCaps); + CPPUNIT_TEST(testReconnectTriggersChangeAndClearsCaps); + CPPUNIT_TEST(testHashAvailable); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + capsProvider = new DummyCapsProvider(); + + user1 = JID("user1@bar.com/bla"); + discoInfo1 = boost::shared_ptr<DiscoInfo>(new DiscoInfo()); + discoInfo1->addFeature("http://swift.im/feature1"); + capsInfo1 = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator("http://node1.im").generateCapsInfo(*discoInfo1.get()))); + capsInfo1alt = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo1.get()))); + user2 = JID("user2@foo.com/baz"); + discoInfo2 = boost::shared_ptr<DiscoInfo>(new DiscoInfo()); + discoInfo2->addFeature("http://swift.im/feature2"); + capsInfo2 = boost::shared_ptr<CapsInfo>(new CapsInfo(CapsInfoGenerator("http://node2.im").generateCapsInfo(*discoInfo2.get()))); + user3 = JID("user3@foo.com/baz"); + legacyCapsInfo = boost::shared_ptr<CapsInfo>(new CapsInfo("http://swift.im", "ver1", "")); + } + + void tearDown() { + delete capsProvider; + delete stanzaChannel; + } + + void testReceiveKnownHash() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + sendPresenceWithCaps(user1, capsInfo1); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1, changes[0]); + CPPUNIT_ASSERT_EQUAL(discoInfo1, testling->getCaps(user1)); + } + + void testReceiveKnownHashTwiceDoesNotTriggerChange() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + sendPresenceWithCaps(user1, capsInfo1); + changes.clear(); + + sendPresenceWithCaps(user1, capsInfo1); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changes.size())); + } + + void testReceiveUnknownHashDoesNotTriggerChange() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + sendPresenceWithCaps(user1, capsInfo1); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(changes.size())); + } + + void testHashAvailable() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + sendPresenceWithCaps(user1, capsInfo1); + + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + capsProvider->onCapsAvailable(capsInfo1->getVersion()); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1, changes[0]); + CPPUNIT_ASSERT_EQUAL(discoInfo1, testling->getCaps(user1)); + } + + void testReceiveUnknownHashAfterKnownHashTriggersChangeAndClearsCaps() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + sendPresenceWithCaps(user1, capsInfo1); + changes.clear(); + sendPresenceWithCaps(user1, capsInfo2); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1, changes[0]); + CPPUNIT_ASSERT(!testling->getCaps(user1)); + } + + void testReceiveUnavailablePresenceAfterKnownHashTriggersChangeAndClearsCaps() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + sendPresenceWithCaps(user1, capsInfo1); + changes.clear(); + sendUnavailablePresence(user1); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1, changes[0]); + CPPUNIT_ASSERT(!testling->getCaps(user1)); + } + + void testReconnectTriggersChangeAndClearsCaps() { + std::auto_ptr<EntityCapsManager> testling = createManager(); + capsProvider->caps[capsInfo1->getVersion()] = discoInfo1; + capsProvider->caps[capsInfo2->getVersion()] = discoInfo2; + sendPresenceWithCaps(user1, capsInfo1); + sendPresenceWithCaps(user2, capsInfo2); + changes.clear(); + stanzaChannel->setAvailable(false); + stanzaChannel->setAvailable(true); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(changes.size())); + CPPUNIT_ASSERT_EQUAL(user1, changes[0]); + CPPUNIT_ASSERT(!testling->getCaps(user1)); + CPPUNIT_ASSERT_EQUAL(user2, changes[1]); + CPPUNIT_ASSERT(!testling->getCaps(user2)); + } + + private: + std::auto_ptr<EntityCapsManager> createManager() { + std::auto_ptr<EntityCapsManager> manager(new EntityCapsManager(capsProvider, stanzaChannel)); + manager->onCapsChanged.connect(boost::bind(&EntityCapsManagerTest::handleCapsChanged, this, _1)); + return manager; + } + + void handleCapsChanged(const JID& jid) { + changes.push_back(jid); + } + + void sendPresenceWithCaps(const JID& jid, boost::shared_ptr<CapsInfo> caps) { + boost::shared_ptr<Presence> presence(new Presence()); + presence->setFrom(jid); + presence->addPayload(caps); + stanzaChannel->onPresenceReceived(presence); + } + + void sendUnavailablePresence(const JID& jid) { + boost::shared_ptr<Presence> presence(new Presence()); + presence->setFrom(jid); + presence->setType(Presence::Unavailable); + stanzaChannel->onPresenceReceived(presence); + } + + private: + struct DummyCapsProvider : public CapsProvider { + virtual DiscoInfo::ref getCaps(const String& hash) const { + std::map<String, DiscoInfo::ref>::const_iterator i = caps.find(hash); + if (i != caps.end()) { + return i->second; + } + return DiscoInfo::ref(); + } + + std::map<String, DiscoInfo::ref> caps; + }; + + private: + DummyStanzaChannel* stanzaChannel; + DummyCapsProvider* capsProvider; + JID user1; + boost::shared_ptr<DiscoInfo> discoInfo1; + boost::shared_ptr<CapsInfo> capsInfo1; + boost::shared_ptr<CapsInfo> capsInfo1alt; + JID user2; + boost::shared_ptr<DiscoInfo> discoInfo2; + boost::shared_ptr<CapsInfo> capsInfo2; + boost::shared_ptr<CapsInfo> legacyCapsInfo; + JID user3; + std::vector<JID> changes; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(EntityCapsManagerTest); |