/* * Copyright (c) 2014 Kevin Smith and 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 <boost/bind.hpp> #include <Swiften/JID/JID.h> #include <string> #include <Swiften/Avatars/AvatarManagerImpl.h> #include <Swiften/Avatars/CombinedAvatarProvider.h> #include <Swiften/Avatars/VCardAvatarManager.h> #include <Swiften/Avatars/OfflineAvatarManager.h> #include <Swiften/Elements/VCardUpdate.h> #include <Swiften/MUC/MUCRegistry.h> #include <Swiften/Client/DummyStanzaChannel.h> #include <Swiften/Crypto/CryptoProvider.h> #include <Swiften/Crypto/PlatformCryptoProvider.h> #include <Swiften/Queries/IQRouter.h> #include <Swiften/Avatars/AvatarMemoryStorage.h> #include <Swiften/VCards/VCardMemoryStorage.h> #include <Swiften/VCards/VCardManager.h> #include <Swiften/Avatars/VCardUpdateAvatarManager.h> #include <Swiften/StringCodecs/Hexify.h> using namespace Swift; class AvatarManagerImplTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(AvatarManagerImplTest); CPPUNIT_TEST(testGetSetAvatar); CPPUNIT_TEST_SUITE_END(); public: void setUp() { ownerJID = JID("owner@domain.com/theowner"); stanzaChannel = boost::make_shared<DummyStanzaChannel>(); iqRouter = boost::make_shared<IQRouter>(stanzaChannel.get()); crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); vcardStorage = boost::make_shared<VCardMemoryStorage>(crypto.get()); vcardManager = boost::make_shared<VCardManager>(ownerJID, iqRouter.get(), vcardStorage.get()); avatarStorage = boost::make_shared<AvatarMemoryStorage>(); mucRegistry = boost::make_shared<DummyMUCRegistry>(); avatarManager = boost::make_shared<AvatarManagerImpl>(vcardManager.get(), stanzaChannel.get(), avatarStorage.get(), crypto.get(), mucRegistry.get()); } void testGetSetAvatar() { /* initially we have no knowledge of the user or their avatar */ JID personJID("person@domain.com/theperson"); ByteArray avatar = avatarManager->getAvatar(personJID.toBare()); CPPUNIT_ASSERT(!avatar.size()); /* notify the 'owner' JID that our avatar has changed */ ByteArray fullAvatar = createByteArray("abcdefg"); boost::shared_ptr<VCardUpdate> vcardUpdate = boost::make_shared<VCardUpdate>(); vcardUpdate->setPhotoHash(Hexify::hexify(crypto->getSHA1Hash(fullAvatar))); boost::shared_ptr<Presence> presence = boost::make_shared<Presence>(); presence->setTo(ownerJID); presence->setFrom(personJID); presence->setType(Presence::Available); presence->addPayload(vcardUpdate); stanzaChannel->onPresenceReceived(presence); /* reply to the avatar request with our new avatar */ CPPUNIT_ASSERT_EQUAL(size_t(1), stanzaChannel->sentStanzas.size()); boost::shared_ptr<IQ> request = boost::dynamic_pointer_cast<IQ>(stanzaChannel->sentStanzas[0]); stanzaChannel->sentStanzas.pop_back(); CPPUNIT_ASSERT(!!request); boost::shared_ptr<VCard> vcard = request->getPayload<VCard>(); CPPUNIT_ASSERT(!!vcard); boost::shared_ptr<IQ> reply = boost::make_shared<IQ>(IQ::Result); reply->setTo(request->getFrom()); reply->setFrom(request->getTo()); reply->setID(request->getID()); vcard->setPhoto(fullAvatar); reply->addPayload(vcard); stanzaChannel->onIQReceived(reply); /* check hash through avatarManager that it received the correct photo */ ByteArray reportedAvatar = avatarManager->getAvatar(personJID.toBare()); CPPUNIT_ASSERT_EQUAL(byteArrayToString(fullAvatar), byteArrayToString(reportedAvatar)); /* send new presence to notify of blank avatar */ vcardUpdate = boost::make_shared<VCardUpdate>(); presence = boost::make_shared<Presence>(); presence->setTo(ownerJID); presence->setFrom(personJID); presence->setType(Presence::Available); presence->addPayload(vcardUpdate); stanzaChannel->onPresenceReceived(presence); /* reply to the avatar request with our EMPTY avatar */ CPPUNIT_ASSERT_EQUAL(size_t(1), stanzaChannel->sentStanzas.size()); request = boost::dynamic_pointer_cast<IQ>(stanzaChannel->sentStanzas[0]); stanzaChannel->sentStanzas.pop_back(); CPPUNIT_ASSERT(!!request); vcard = request->getPayload<VCard>(); CPPUNIT_ASSERT(!!vcard); ByteArray blankAvatar = createByteArray(""); reply = boost::make_shared<IQ>(IQ::Result); reply->setTo(request->getFrom()); reply->setFrom(request->getTo()); reply->setID(request->getID()); vcard->setPhoto(blankAvatar); reply->addPayload(vcard); stanzaChannel->onIQReceived(reply); /* check hash through avatarManager that it received the correct photo */ reportedAvatar = avatarManager->getAvatar(personJID.toBare()); CPPUNIT_ASSERT_EQUAL(byteArrayToString(blankAvatar), byteArrayToString(reportedAvatar)); } struct DummyMUCRegistry : public MUCRegistry { bool isMUC(const JID& jid) const { return std::find(mucs_.begin(), mucs_.end(), jid) != mucs_.end(); } std::vector<JID> mucs_; }; private: JID ownerJID; boost::shared_ptr<DummyStanzaChannel> stanzaChannel; boost::shared_ptr<IQRouter> iqRouter; boost::shared_ptr<CryptoProvider> crypto; boost::shared_ptr<VCardMemoryStorage> vcardStorage; boost::shared_ptr<VCardManager> vcardManager; boost::shared_ptr<AvatarMemoryStorage> avatarStorage; boost::shared_ptr<DummyMUCRegistry> mucRegistry; boost::shared_ptr<AvatarManagerImpl> avatarManager; }; CPPUNIT_TEST_SUITE_REGISTRATION(AvatarManagerImplTest);