From 9d9fb66aefef85a1c5ad432391014d15011747d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 23 Oct 2010 23:08:19 +0200 Subject: Added ClientDiscoManager. diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index f3b9977..5556a00 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -48,9 +48,9 @@ #include "Swiften/Elements/VCardUpdate.h" #include "Swift/Controllers/Settings/SettingsProvider.h" #include "Swiften/Elements/DiscoInfo.h" -#include "Swiften/Disco/DiscoInfoResponder.h" #include "Swiften/Disco/CapsInfoGenerator.h" #include "Swiften/Disco/GetDiscoInfoRequest.h" +#include "Swiften/Disco/ClientDiscoManager.h" #include "Swiften/VCards/GetVCardRequest.h" #include "Swiften/StringCodecs/SHA1.h" #include "Swiften/StringCodecs/Hexify.h" @@ -99,7 +99,6 @@ MainController::MainController( rosterController_ = NULL; chatsManager_ = NULL; eventWindowController_ = NULL; - discoResponder_ = NULL; mucSearchController_ = NULL; quitRequested_ = false; @@ -173,11 +172,6 @@ void MainController::resetClient() { resetPendingReconnects(); delete mucSearchController_; mucSearchController_ = NULL; - if (discoResponder_) { - discoResponder_->stop(); - delete discoResponder_; - discoResponder_ = NULL; - } delete eventWindowController_; eventWindowController_ = NULL; delete chatsManager_; @@ -247,12 +241,8 @@ void MainController::handleConnected() { discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); discoInfo.addFeature("urn:xmpp:sec-label:0"); discoInfo.addFeature(ChatState::getFeatureNamespace()); - capsInfo_ = boost::shared_ptr(new CapsInfo(CapsInfoGenerator(CLIENT_NODE).generateCapsInfo(discoInfo))); - - discoResponder_ = new DiscoInfoResponder(client_->getIQRouter()); - discoResponder_->setDiscoInfo(discoInfo); - discoResponder_->setDiscoInfo(capsInfo_->getNode() + "#" + capsInfo_->getVersion(), discoInfo); - discoResponder_->start(); + client_->getDiscoManager()->setCapsNode(CLIENT_NODE); + client_->getDiscoManager()->setDiscoInfo(discoInfo); mucSearchController_ = new MUCSearchController(jid_, uiEventStream_, mucSearchWindowFactory_, client_->getIQRouter()); } @@ -317,7 +307,6 @@ void MainController::sendPresence(boost::shared_ptr presence) { if (!vCardPhotoHash_.isEmpty()) { presence->updatePayload(boost::shared_ptr(new VCardUpdate(vCardPhotoHash_))); } - presence->updatePayload(capsInfo_); client_->getPresenceSender()->sendPresence(presence); if (presence->getType() == Presence::Unavailable) { logout(); diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index c36c136..c05d098 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -17,8 +17,8 @@ #include "Swiften/Base/String.h" #include "Swiften/Client/ClientError.h" #include "Swiften/JID/JID.h" -#include "Swiften/Elements/VCard.h" #include "Swiften/Elements/DiscoInfo.h" +#include "Swiften/Elements/VCard.h" #include "Swiften/Elements/ErrorPayload.h" #include "Swiften/Elements/Presence.h" #include "Swift/Controllers/Settings/SettingsProvider.h" @@ -38,7 +38,6 @@ namespace Swift { class MainWindowFactory; class MainWindow; class RosterController; - class DiscoInfoResponder; class LoginWindow; class EventLoop; class LoginWindowFactory; @@ -132,11 +131,9 @@ namespace Swift { EventController* eventController_; EventWindowController* eventWindowController_; LoginWindow* loginWindow_; - DiscoInfoResponder* discoResponder_; UIEventStream* uiEventStream_; XMLConsoleController* xmlConsoleController_; ChatsManager* chatsManager_; - boost::shared_ptr capsInfo_; JID jid_; JID boundJID_; SystemTrayController* systemTrayController_; diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 7dbcb70..fd01e25 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -20,6 +20,7 @@ #include "Swiften/Avatars/AvatarManagerImpl.h" #include "Swiften/Disco/CapsManager.h" #include "Swiften/Disco/EntityCapsManager.h" +#include "Swiften/Disco/ClientDiscoManager.h" #include "Swiften/Client/NickResolver.h" #include "Swiften/Presence/SubscriptionManager.h" @@ -41,6 +42,7 @@ Client::Client(EventLoop* eventLoop, const JID& jid, const String& password, Sto stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel()); directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender); + discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender); mucRegistry = new MUCRegistry(); mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry); @@ -64,6 +66,7 @@ Client::~Client() { delete mucManager; delete mucRegistry; + delete discoManager; delete directedPresenceSender; delete stanzaChannelPresenceSender; @@ -106,7 +109,7 @@ Storages* Client::getStorages() const { } PresenceSender* Client::getPresenceSender() const { - return directedPresenceSender; + return discoManager->getPresenceSender(); } } diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index adfd549..a17fe24 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -27,6 +27,7 @@ namespace Swift { class EntityCapsManager; class NickResolver; class SubscriptionManager; + class ClientDiscoManager; /** * Provides the core functionality for writing XMPP client software. @@ -122,6 +123,10 @@ namespace Swift { return subscriptionManager; } + ClientDiscoManager* getDiscoManager() const { + return discoManager; + } + public: /** * This signal is emitted when a JID changes presence. @@ -151,5 +156,6 @@ namespace Swift { NickResolver* nickResolver; SubscriptionManager* subscriptionManager; MUCManager* mucManager; + ClientDiscoManager* discoManager; }; } diff --git a/Swiften/Client/DummyStanzaChannel.h b/Swiften/Client/DummyStanzaChannel.h index b8ae545..d9fb138 100644 --- a/Swiften/Client/DummyStanzaChannel.h +++ b/Swiften/Client/DummyStanzaChannel.h @@ -56,6 +56,10 @@ namespace Swift { return iqStanza && iqStanza->getType() == type && iqStanza->getTo() == jid && iqStanza->getPayload(); } + template boost::shared_ptr getStanzaAtIndex(size_t index) { + return boost::dynamic_pointer_cast(sentStanzas[index]); + } + std::vector > sentStanzas; bool available_; }; diff --git a/Swiften/Disco/ClientDiscoManager.cpp b/Swiften/Disco/ClientDiscoManager.cpp new file mode 100644 index 0000000..6753df2 --- /dev/null +++ b/Swiften/Disco/ClientDiscoManager.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Disco/ClientDiscoManager.h" + +#include "Swiften/Disco/DiscoInfoResponder.h" +#include "Swiften/Disco/CapsInfoGenerator.h" +#include "Swiften/Presence/PayloadAddingPresenceSender.h" + +namespace Swift { + +ClientDiscoManager::ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender) { + discoInfoResponder = new DiscoInfoResponder(iqRouter); + discoInfoResponder->start(); + this->presenceSender = new PayloadAddingPresenceSender(presenceSender); +} + +ClientDiscoManager::~ClientDiscoManager() { + delete presenceSender; + discoInfoResponder->stop(); + delete discoInfoResponder; +} + +void ClientDiscoManager::setCapsNode(const String& node) { + capsNode = node; +} + +void ClientDiscoManager::setDiscoInfo(const DiscoInfo& discoInfo) { + capsInfo = CapsInfo::ref(new CapsInfo(CapsInfoGenerator(capsNode).generateCapsInfo(discoInfo))); + discoInfoResponder->clearDiscoInfo(); + discoInfoResponder->setDiscoInfo(discoInfo); + discoInfoResponder->setDiscoInfo(capsInfo->getNode() + "#" + capsInfo->getVersion(), discoInfo); + presenceSender->setPayload(capsInfo); +} + +} diff --git a/Swiften/Disco/ClientDiscoManager.h b/Swiften/Disco/ClientDiscoManager.h new file mode 100644 index 0000000..b997374 --- /dev/null +++ b/Swiften/Disco/ClientDiscoManager.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Elements/CapsInfo.h" +#include "Swiften/Elements/DiscoInfo.h" +#include "Swiften/Presence/PayloadAddingPresenceSender.h" + +namespace Swift { + class IQRouter; + class DiscoInfoResponder; + class PayloadAddingPresenceSender; + class PresenceSender; + + /** + * Class responsible for managing outgoing disco information for a client. + * + * The manager will respond to disco#info requests, and add entity capabilities information + * to outgoing presence. + * + * To use this class, call setCapsNode() once with the caps URI of the client. After this, + * call setDiscoInfo() with the capabilities for the client. This can be + * called whenever the capabilities change. + */ + class ClientDiscoManager { + public: + /** + * Constructs the manager + * + * \param iqRouter the router on which requests will be answered + * \param presenceSender the presence sender to which all outgoing presence + * (with caps information) will be sent. + */ + ClientDiscoManager(IQRouter* iqRouter, PresenceSender* presenceSender); + ~ClientDiscoManager(); + + /** + * Needs to be called before calling setDiscoInfo(). + */ + void setCapsNode(const String& node); + + /** + * Sets the capabilities of the client. + */ + void setDiscoInfo(const DiscoInfo& info); + + /** + * Returns the presence sender through which all outgoing presence + * should be sent. + * The manager will add the necessary caps information, and forward it to + * the presence sender passed at construction time. + */ + PresenceSender* getPresenceSender() const { + return presenceSender; + } + + private: + PayloadAddingPresenceSender* presenceSender; + DiscoInfoResponder* discoInfoResponder; + String capsNode; + CapsInfo::ref capsInfo; + }; +} diff --git a/Swiften/Disco/DiscoInfoResponder.cpp b/Swiften/Disco/DiscoInfoResponder.cpp index 154eded..2e686c7 100644 --- a/Swiften/Disco/DiscoInfoResponder.cpp +++ b/Swiften/Disco/DiscoInfoResponder.cpp @@ -13,6 +13,11 @@ namespace Swift { DiscoInfoResponder::DiscoInfoResponder(IQRouter* router) : GetResponder(router) { } +void DiscoInfoResponder::clearDiscoInfo() { + info_ = DiscoInfo(); + nodeInfo_.clear(); +} + void DiscoInfoResponder::setDiscoInfo(const DiscoInfo& info) { info_ = info; } diff --git a/Swiften/Disco/DiscoInfoResponder.h b/Swiften/Disco/DiscoInfoResponder.h index 4a7d271..0dc1172 100644 --- a/Swiften/Disco/DiscoInfoResponder.h +++ b/Swiften/Disco/DiscoInfoResponder.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_DiscoInfoResponder_H -#define SWIFTEN_DiscoInfoResponder_H +#pragma once #include @@ -19,6 +18,7 @@ namespace Swift { public: DiscoInfoResponder(IQRouter* router); + void clearDiscoInfo(); void setDiscoInfo(const DiscoInfo& info); void setDiscoInfo(const String& node, const DiscoInfo& info); @@ -30,5 +30,3 @@ namespace Swift { std::map nodeInfo_; }; } - -#endif diff --git a/Swiften/Disco/SConscript b/Swiften/Disco/SConscript index 3838d0e..a791946 100644 --- a/Swiften/Disco/SConscript +++ b/Swiften/Disco/SConscript @@ -7,6 +7,7 @@ objects = swiften_env.StaticObject([ "EntityCapsProvider.cpp", "CapsStorage.cpp", "CapsFileStorage.cpp", + "ClientDiscoManager.cpp", "DiscoInfoResponder.cpp", ]) swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Elements/Body.h b/Swiften/Elements/Body.h index e3610c8..8262e09 100644 --- a/Swiften/Elements/Body.h +++ b/Swiften/Elements/Body.h @@ -4,8 +4,7 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_Body_H -#define SWIFTEN_Body_H +#pragma once #include "Swiften/Elements/Payload.h" #include "Swiften/Base/String.h" @@ -13,6 +12,8 @@ namespace Swift { class Body : public Payload { public: + typedef boost::shared_ptr ref; + Body(const String& text = "") : text_(text) { } @@ -28,5 +29,3 @@ namespace Swift { String text_; }; } - -#endif diff --git a/Swiften/Elements/CapsInfo.h b/Swiften/Elements/CapsInfo.h index 1968a29..dc3cc2e 100644 --- a/Swiften/Elements/CapsInfo.h +++ b/Swiften/Elements/CapsInfo.h @@ -6,13 +6,16 @@ #pragma once -#include "Swiften/Base/String.h" +#include +#include "Swiften/Base/String.h" #include "Swiften/Elements/Payload.h" namespace Swift { class CapsInfo : public Payload { public: + typedef boost::shared_ptr ref; + CapsInfo(const String& node = "", const String& version = "", const String& hash = "sha-1") : node_(node), version_(version), hash_(hash) {} bool operator==(const CapsInfo& o) const { diff --git a/Swiften/Elements/Payload.h b/Swiften/Elements/Payload.h index 9d7ed16..c87b899 100644 --- a/Swiften/Elements/Payload.h +++ b/Swiften/Elements/Payload.h @@ -4,14 +4,15 @@ * See Documentation/Licenses/GPLv3.txt for more information. */ -#ifndef SWIFTEN_PAYLOAD_H -#define SWIFTEN_PAYLOAD_H +#pragma once + +#include namespace Swift { class Payload { public: + typedef boost::shared_ptr ref; + virtual ~Payload(); }; } - -#endif diff --git a/Swiften/Presence/PayloadAddingPresenceSender.cpp b/Swiften/Presence/PayloadAddingPresenceSender.cpp new file mode 100644 index 0000000..c3d1638 --- /dev/null +++ b/Swiften/Presence/PayloadAddingPresenceSender.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Presence/PayloadAddingPresenceSender.h" + +namespace Swift { + +PayloadAddingPresenceSender::PayloadAddingPresenceSender(PresenceSender* sender) : sender(sender) { +} + +void PayloadAddingPresenceSender::sendPresence(Presence::ref presence) { + if (presence->isAvailable()) { + if (!presence->getTo().isValid()) { + lastSentPresence = presence; + } + } + else { + lastSentPresence.reset(); + } + if (payload) { + Presence::ref sentPresence = Presence::create(presence); + sentPresence->updatePayload(payload); + sender->sendPresence(sentPresence); + } + else { + sender->sendPresence(presence); + } +} + +bool PayloadAddingPresenceSender::isAvailable() const { + return sender->isAvailable(); +} + +void PayloadAddingPresenceSender::setPayload(Payload::ref payload) { + this->payload = payload; + if (lastSentPresence) { + sendPresence(lastSentPresence); + } +} + +} diff --git a/Swiften/Presence/PayloadAddingPresenceSender.h b/Swiften/Presence/PayloadAddingPresenceSender.h new file mode 100644 index 0000000..5602ebe --- /dev/null +++ b/Swiften/Presence/PayloadAddingPresenceSender.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#pragma once + +#include "Swiften/Presence/PresenceSender.h" +#include "Swiften/Elements/Payload.h" + +namespace Swift { + class StanzaChannel; + + /** + * This presence sender adds payloads to outgoing presences. + * + * + */ + class PayloadAddingPresenceSender : public PresenceSender { + public: + PayloadAddingPresenceSender(PresenceSender*); + + void sendPresence(Presence::ref); + bool isAvailable() const; + + void setPayload(Payload::ref); + + private: + Presence::ref lastSentPresence; + PresenceSender* sender; + Payload::ref payload; + }; +} diff --git a/Swiften/Presence/SConscript b/Swiften/Presence/SConscript new file mode 100644 index 0000000..6911d45 --- /dev/null +++ b/Swiften/Presence/SConscript @@ -0,0 +1,11 @@ +Import("swiften_env") + +objects = swiften_env.StaticObject([ + "PresenceOracle.cpp", + "PresenceSender.cpp", + "DirectedPresenceSender.cpp", + "PayloadAddingPresenceSender.cpp", + "StanzaChannelPresenceSender.cpp", + "SubscriptionManager.cpp", + ]) +swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp new file mode 100644 index 0000000..3a6487a --- /dev/null +++ b/Swiften/Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2010 Remko Tronçon + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include +#include +#include +#include + +#include "Swiften/Presence/PayloadAddingPresenceSender.h" +#include "Swiften/Presence/StanzaChannelPresenceSender.h" +#include "Swiften/Elements/Body.h" +#include "Swiften/Client/DummyStanzaChannel.h" + +using namespace Swift; + +class PayloadAddingPresenceSenderTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(PayloadAddingPresenceSenderTest); + CPPUNIT_TEST(testSetPayloadAddsPayloadOnPresenceSend); + CPPUNIT_TEST(testSetNullPayloadDoesNotAddPayloadOnPresenceSend); + CPPUNIT_TEST(testSendPresenceDoesNotAlterOriginalPayload); + CPPUNIT_TEST(testSetPayloadAfterInitialPresenceResendsPresence); + CPPUNIT_TEST(testSetPayloadAfterUnavailablePresenceDoesNotResendPresence); + CPPUNIT_TEST(testSendDirectedPresenceIsNotResent); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + presenceSender = new StanzaChannelPresenceSender(stanzaChannel); + } + + void tearDown() { + delete presenceSender; + delete stanzaChannel; + } + + void testSetPayloadAddsPayloadOnPresenceSend() { + std::auto_ptr testling(createSender()); + + testling->setPayload(MyPayload::create("foo")); + testling->sendPresence(Presence::create("bar")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex(0)->getStatus()); + CPPUNIT_ASSERT(stanzaChannel->getStanzaAtIndex(0)->getPayload()); + } + + void testSetNullPayloadDoesNotAddPayloadOnPresenceSend() { + std::auto_ptr testling(createSender()); + + testling->setPayload(MyPayload::ref()); + testling->sendPresence(Presence::create("bar")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex(0)->getStatus()); + CPPUNIT_ASSERT(!stanzaChannel->getStanzaAtIndex(0)->getPayload()); + } + + void testSendPresenceDoesNotAlterOriginalPayload() { + std::auto_ptr testling(createSender()); + + testling->setPayload(MyPayload::create("foo")); + Presence::ref presence(Presence::create("bar")); + testling->sendPresence(presence); + + CPPUNIT_ASSERT(!presence->getPayload()); + } + + void testSetPayloadAfterInitialPresenceResendsPresence() { + std::auto_ptr testling(createSender()); + + testling->sendPresence(Presence::create("bar")); + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(2, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex(1)->getStatus()); + CPPUNIT_ASSERT(stanzaChannel->getStanzaAtIndex(1)->getPayload()); + } + + void testSetPayloadAfterUnavailablePresenceDoesNotResendPresence() { + std::auto_ptr testling(createSender()); + + Presence::ref presence = Presence::create("bar"); + presence->setType(Presence::Unavailable); + testling->sendPresence(presence); + + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(1, static_cast(stanzaChannel->sentStanzas.size())); + } + + void testSendDirectedPresenceIsNotResent() { + std::auto_ptr testling(createSender()); + + testling->sendPresence(Presence::create("bar")); + Presence::ref directedPresence = Presence::create("baz"); + directedPresence->setTo(JID("foo@bar.com")); + testling->sendPresence(directedPresence); + testling->setPayload(MyPayload::create("foo")); + + CPPUNIT_ASSERT_EQUAL(3, static_cast(stanzaChannel->sentStanzas.size())); + CPPUNIT_ASSERT_EQUAL(String("bar"), stanzaChannel->getStanzaAtIndex(2)->getStatus()); + } + + private: + std::auto_ptr createSender() { + std::auto_ptr sender(new PayloadAddingPresenceSender(presenceSender)); + return sender; + } + + struct MyPayload : public Payload { + typedef boost::shared_ptr ref; + + MyPayload(const String& body) : body(body) {} + + static ref create(const String& body) { + return ref(new MyPayload(body)); + } + + String body; + }; + + private: + DummyStanzaChannel* stanzaChannel; + StanzaChannelPresenceSender* presenceSender; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PayloadAddingPresenceSenderTest); diff --git a/Swiften/SConscript b/Swiften/SConscript index 5790672..9744f45 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -51,11 +51,6 @@ if env["SCONS_STAGE"] == "build" : "MUC/MUCOccupant.cpp", "MUC/MUCRegistry.cpp", "MUC/MUCBookmarkManager.cpp", - "Presence/PresenceOracle.cpp", - "Presence/PresenceSender.cpp", - "Presence/DirectedPresenceSender.cpp", - "Presence/StanzaChannelPresenceSender.cpp", - "Presence/SubscriptionManager.cpp", "Queries/IQChannel.cpp", "Queries/IQHandler.cpp", "Queries/IQRouter.cpp", @@ -139,6 +134,7 @@ if env["SCONS_STAGE"] == "build" : "Disco", "VCards", "Network", + "Presence", "FileTransfer", "History", "StreamStack", @@ -223,6 +219,7 @@ if env["SCONS_STAGE"] == "build" : File("Parser/UnitTest/XMPPParserTest.cpp"), File("Presence/UnitTest/PresenceOracleTest.cpp"), File("Presence/UnitTest/DirectedPresenceSenderTest.cpp"), + File("Presence/UnitTest/PayloadAddingPresenceSenderTest.cpp"), File("Queries/Requests/UnitTest/GetPrivateStorageRequestTest.cpp"), File("Disco/UnitTest/DiscoInfoResponderTest.cpp"), File("Queries/UnitTest/IQRouterTest.cpp"), -- cgit v0.10.2-6-g49f6