summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2013-03-08 15:17:30 (GMT)
committerTobias Markmann <tm@ayena.de>2013-03-27 14:12:26 (GMT)
commit497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04 (patch)
treedc81e56199f54cf20f834c78bda7fc26ffbc38f9 /Swiften
parent20ead0a84fdd8c9e870e98ee6a2712bfa263d7fb (diff)
downloadswift-497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04.zip
swift-497b647fe034a3d2cdc6d75ce0ff70e3df3aaf04.tar.bz2
Adding support for Blocking Command (XEP-0191) to Swift(-en).
Change-Id: I7c92518dc389474d520d4cf96f96a11459f73d26 License: This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.
Diffstat (limited to 'Swiften')
-rw-r--r--Swiften/Client/BlockList.cpp9
-rw-r--r--Swiften/Client/BlockList.h7
-rw-r--r--Swiften/Client/BlockListImpl.cpp32
-rw-r--r--Swiften/Client/BlockListImpl.h4
-rw-r--r--Swiften/Client/Client.cpp2
-rw-r--r--Swiften/Client/Client.h8
-rw-r--r--Swiften/Client/ClientBlockListManager.cpp32
-rw-r--r--Swiften/Client/ClientBlockListManager.h10
-rw-r--r--Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp190
-rw-r--r--Swiften/Elements/BlockListPayload.h2
-rw-r--r--Swiften/Elements/BlockPayload.h2
-rw-r--r--Swiften/Elements/DiscoInfo.cpp1
-rw-r--r--Swiften/Elements/DiscoInfo.h1
-rw-r--r--Swiften/Elements/UnblockPayload.h2
-rw-r--r--Swiften/Parser/PayloadParsers/BlockParser.h3
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/BlockParserTest.cpp72
-rw-r--r--Swiften/Queries/GenericRequest.h5
-rw-r--r--Swiften/SConscript3
-rw-r--r--Swiften/Serializer/PayloadSerializers/BlockSerializer.h2
-rw-r--r--Swiften/Serializer/PayloadSerializers/UnitTest/BlockSerializerTest.cpp55
20 files changed, 419 insertions, 23 deletions
diff --git a/Swiften/Client/BlockList.cpp b/Swiften/Client/BlockList.cpp
index 0b2fc12..3ee7864 100644
--- a/Swiften/Client/BlockList.cpp
+++ b/Swiften/Client/BlockList.cpp
@@ -6,8 +6,17 @@
#include <Swiften/Client/BlockList.h>
+#include <algorithm>
+
using namespace Swift;
BlockList::~BlockList() {
}
+
+bool BlockList::isBlocked(const JID& jid) const {
+ const std::vector<JID>& items = getItems();
+ return (std::find(items.begin(), items.end(), jid.toBare()) != items.end()) ||
+ (std::find(items.begin(), items.end(), JID(jid.getDomain())) != items.end()) ||
+ (std::find(items.begin(), items.end(), jid) != items.end());
+}
diff --git a/Swiften/Client/BlockList.h b/Swiften/Client/BlockList.h
index d8cff60..99c83c1 100644
--- a/Swiften/Client/BlockList.h
+++ b/Swiften/Client/BlockList.h
@@ -6,7 +6,7 @@
#pragma once
-#include <set>
+#include <vector>
#include <Swiften/JID/JID.h>
#include <Swiften/Base/boost_bsignals.h>
@@ -15,6 +15,7 @@ namespace Swift {
class BlockList {
public:
enum State {
+ Init,
Requesting,
Available,
Error
@@ -23,7 +24,9 @@ namespace Swift {
virtual State getState() const = 0;
- virtual const std::set<JID>& getItems() const = 0;
+ virtual const std::vector<JID>& getItems() const = 0;
+
+ bool isBlocked(const JID& jid) const;
public:
boost::signal<void ()> onStateChanged;
diff --git a/Swiften/Client/BlockListImpl.cpp b/Swiften/Client/BlockListImpl.cpp
index dfaaaf1..5950233 100644
--- a/Swiften/Client/BlockListImpl.cpp
+++ b/Swiften/Client/BlockListImpl.cpp
@@ -8,30 +8,47 @@
#include <Swiften/Base/foreach.h>
+#include <algorithm>
+
using namespace Swift;
-BlockListImpl::BlockListImpl() {
+BlockListImpl::BlockListImpl() : state(Init) {
}
void BlockListImpl::setItems(const std::vector<JID>& items) {
- this->items = std::set<JID>(items.begin(), items.end());
+ foreach (const JID& jid, this->items) {
+ if (std::find(items.begin(), items.end(), jid) != items.end()) {
+ onItemRemoved(jid);
+ }
+ }
+
+ foreach (const JID& jid, items) {
+ if (std::find(this->items.begin(), this->items.end(), jid) != this->items.end()) {
+ onItemAdded(jid);
+ }
+ }
+ this->items = items;
}
void BlockListImpl::addItem(const JID& item) {
- if (items.insert(item).second) {
+ if (std::find(items.begin(), items.end(), item) == items.end()) {
+ items.push_back(item);
onItemAdded(item);
}
}
void BlockListImpl::removeItem(const JID& item) {
- if (items.erase(item)) {
+ size_t oldSize = items.size();
+ items.erase(std::remove(items.begin(), items.end(), item), items.end());
+ if (items.size() != oldSize) {
onItemRemoved(item);
}
}
void BlockListImpl::setState(State state) {
if (this->state != state) {
+ this->state = state;
onStateChanged();
}
}
@@ -43,14 +60,13 @@ void BlockListImpl::addItems(const std::vector<JID>& items) {
}
void BlockListImpl::removeItems(const std::vector<JID>& items) {
- foreach (const JID& item, items) {
+ std::vector<JID> itemsToRemove = items;
+ foreach (const JID& item, itemsToRemove) {
removeItem(item);
}
}
void BlockListImpl::removeAllItems() {
- foreach (const JID& item, items) {
- removeItem(item);
- }
+ removeItems(items);
}
diff --git a/Swiften/Client/BlockListImpl.h b/Swiften/Client/BlockListImpl.h
index ef08340..2a799ae 100644
--- a/Swiften/Client/BlockListImpl.h
+++ b/Swiften/Client/BlockListImpl.h
@@ -19,7 +19,7 @@ namespace Swift {
void setState(State state);
- virtual const std::set<JID>& getItems() const {
+ virtual const std::vector<JID>& getItems() const {
return items;
}
@@ -32,6 +32,6 @@ namespace Swift {
private:
State state;
- std::set<JID> items;
+ std::vector<JID> items;
};
}
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp
index 1a6c64b..00f0f44 100644
--- a/Swiften/Client/Client.cpp
+++ b/Swiften/Client/Client.cpp
@@ -30,6 +30,7 @@
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/FileTransfer/FileTransferManagerImpl.h>
#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+#include <Swiften/Client/ClientBlockListManager.h>
#ifndef SWIFT_EXPERIMENTAL_FT
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#endif
@@ -68,6 +69,7 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
blindCertificateTrustChecker = new BlindCertificateTrustChecker();
jingleSessionManager = new JingleSessionManager(getIQRouter());
+ blockListManager = new ClientBlockListManager(getIQRouter());
fileTransferManager = NULL;
whiteboardSessionManager = NULL;
diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h
index 126572a..f192539 100644
--- a/Swiften/Client/Client.h
+++ b/Swiften/Client/Client.h
@@ -37,6 +37,7 @@ namespace Swift {
class JingleSessionManager;
class FileTransferManager;
class WhiteboardSessionManager;
+ class ClientBlockListManager;
/**
* Provides the core functionality for writing XMPP client software.
@@ -135,6 +136,10 @@ namespace Swift {
ClientDiscoManager* getDiscoManager() const {
return discoManager;
}
+
+ ClientBlockListManager* getClientBlockListManager() const {
+ return blockListManager;
+ }
/**
* Returns a FileTransferManager for the client. This is only available after the onConnected
@@ -188,6 +193,7 @@ namespace Swift {
JingleSessionManager* jingleSessionManager;
FileTransferManager* fileTransferManager;
BlindCertificateTrustChecker* blindCertificateTrustChecker;
- WhiteboardSessionManager* whiteboardSessionManager;
+ WhiteboardSessionManager* whiteboardSessionManager;
+ ClientBlockListManager* blockListManager;
};
}
diff --git a/Swiften/Client/ClientBlockListManager.cpp b/Swiften/Client/ClientBlockListManager.cpp
index 7222cea..6646a5c 100644
--- a/Swiften/Client/ClientBlockListManager.cpp
+++ b/Swiften/Client/ClientBlockListManager.cpp
@@ -66,11 +66,14 @@ namespace {
}
ClientBlockListManager::ClientBlockListManager(IQRouter* iqRouter) : iqRouter(iqRouter) {
+
}
ClientBlockListManager::~ClientBlockListManager() {
- unblockResponder->stop();
- blockResponder->stop();
+ if (blockList && blockList->getState() == BlockList::Available) {
+ unblockResponder->stop();
+ blockResponder->stop();
+ }
if (getRequest) {
getRequest->onResponse.disconnect(boost::bind(&ClientBlockListManager::handleBlockListReceived, this, _1, _2));
}
@@ -88,13 +91,36 @@ boost::shared_ptr<BlockList> ClientBlockListManager::getBlockList() {
return blockList;
}
+GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDRequest(const JID& jid) {
+ return createBlockJIDsRequest(std::vector<JID>(1, jid));
+}
+
+GenericRequest<BlockPayload>::ref ClientBlockListManager::createBlockJIDsRequest(const std::vector<JID>& jids) {
+ boost::shared_ptr<BlockPayload> payload = boost::make_shared<BlockPayload>(jids);
+ return boost::make_shared< GenericRequest<BlockPayload> >(IQ::Set, JID(), payload, iqRouter);
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDRequest(const JID& jid) {
+ return createUnblockJIDsRequest(std::vector<JID>(1, jid));
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockJIDsRequest(const std::vector<JID>& jids) {
+ boost::shared_ptr<UnblockPayload> payload = boost::make_shared<UnblockPayload>(jids);
+ return boost::make_shared< GenericRequest<UnblockPayload> >(IQ::Set, JID(), payload, iqRouter);
+}
+
+GenericRequest<UnblockPayload>::ref ClientBlockListManager::createUnblockAllRequest() {
+ return createUnblockJIDsRequest(std::vector<JID>());
+}
+
+
void ClientBlockListManager::handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref error) {
if (error || !payload) {
blockList->setState(BlockList::Error);
}
else {
- blockList->setState(BlockList::Available);
blockList->setItems(payload->getItems());
+ blockList->setState(BlockList::Available);
blockResponder = boost::make_shared<BlockResponder>(blockList, iqRouter);
blockResponder->start();
unblockResponder = boost::make_shared<UnblockResponder>(blockList, iqRouter);
diff --git a/Swiften/Client/ClientBlockListManager.h b/Swiften/Client/ClientBlockListManager.h
index 21d35e3..e8d4ac6 100644
--- a/Swiften/Client/ClientBlockListManager.h
+++ b/Swiften/Client/ClientBlockListManager.h
@@ -12,6 +12,7 @@
#include <Swiften/Elements/BlockPayload.h>
#include <Swiften/Elements/BlockListPayload.h>
#include <Swiften/Elements/UnblockPayload.h>
+#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Queries/SetResponder.h>
#include <Swiften/Queries/GenericRequest.h>
#include <Swiften/Client/BlockList.h>
@@ -25,13 +26,18 @@ namespace Swift {
ClientBlockListManager(IQRouter *iqRouter);
~ClientBlockListManager();
- bool isSupported() const;
-
/**
* Returns the blocklist.
*/
boost::shared_ptr<BlockList> getBlockList();
+ GenericRequest<BlockPayload>::ref createBlockJIDRequest(const JID& jid);
+ GenericRequest<BlockPayload>::ref createBlockJIDsRequest(const std::vector<JID>& jids);
+
+ GenericRequest<UnblockPayload>::ref createUnblockJIDRequest(const JID& jid);
+ GenericRequest<UnblockPayload>::ref createUnblockJIDsRequest(const std::vector<JID>& jids);
+ GenericRequest<UnblockPayload>::ref createUnblockAllRequest();
+
private:
void handleBlockListReceived(boost::shared_ptr<BlockListPayload> payload, ErrorPayload::ref);
diff --git a/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp b/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp
new file mode 100644
index 0000000..9010042
--- /dev/null
+++ b/Swiften/Client/UnitTest/ClientBlockListManagerTest.cpp
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <algorithm>
+
+#include <Swiften/Base/foreach.h>
+
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Client/ClientBlockListManager.h>
+#include <Swiften/Queries/IQRouter.h>
+#include <Swiften/Elements/IQ.h>
+
+using namespace Swift;
+
+class ClientBlockListManagerTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(ClientBlockListManagerTest);
+ CPPUNIT_TEST(testFetchBlockList);
+ CPPUNIT_TEST(testBlockCommand);
+ CPPUNIT_TEST(testUnblockCommand);
+ CPPUNIT_TEST(testUnblockAllCommand);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ ownJID_ = JID("kev@wonderland.lit");
+ stanzaChannel_ = new DummyStanzaChannel();
+ iqRouter_ = new IQRouter(stanzaChannel_);
+ iqRouter_->setJID(ownJID_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ }
+
+ void testFetchBlockList() {
+ std::vector<JID> blockJids;
+ blockJids.push_back(JID("romeo@montague.net"));
+ blockJids.push_back(JID("iago@shakespeare.lit"));
+ helperInitialBlockListFetch(blockJids);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+ }
+
+ void testBlockCommand() {
+ // start with an already fetched block list
+ helperInitialBlockListFetch(std::vector<JID>(1, JID("iago@shakespeare.lit")));
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<BlockPayload>::ref blockRequest = clientBlockListManager_->createBlockJIDRequest(JID("romeo@montague.net"));
+ blockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<BlockPayload> blockPayload = request->getPayload<BlockPayload>();
+ CPPUNIT_ASSERT(blockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), blockPayload->getItems().at(0));
+
+ IQ::ref blockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(blockRequestResponse);
+ stanzaChannel_->onIQReceived(blockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<BlockPayload> pushPayload = boost::make_shared<BlockPayload>();
+ pushPayload->addItem(JID("romeo@montague.net"));
+ IQ::ref blockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(blockPush);
+ stanzaChannel_->onIQReceived(blockPush);
+
+ std::vector<JID> blockedJIDs = clientBlockListManager_->getBlockList()->getItems();
+ CPPUNIT_ASSERT(blockedJIDs.end() != std::find(blockedJIDs.begin(), blockedJIDs.end(), JID("romeo@montague.net")));
+ }
+
+ void testUnblockCommand() {
+ // start with an already fetched block list
+ std::vector<JID> initialBlockList = std::vector<JID>(1, JID("iago@shakespeare.lit"));
+ initialBlockList.push_back(JID("romeo@montague.net"));
+ helperInitialBlockListFetch(initialBlockList);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<UnblockPayload>::ref unblockRequest = clientBlockListManager_->createUnblockJIDRequest(JID("romeo@montague.net"));
+ unblockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<UnblockPayload> unblockPayload = request->getPayload<UnblockPayload>();
+ CPPUNIT_ASSERT(unblockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), unblockPayload->getItems().at(0));
+
+ IQ::ref unblockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(unblockRequestResponse);
+ stanzaChannel_->onIQReceived(unblockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<UnblockPayload> pushPayload = boost::make_shared<UnblockPayload>();
+ pushPayload->addItem(JID("romeo@montague.net"));
+ IQ::ref unblockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(unblockPush);
+ stanzaChannel_->onIQReceived(unblockPush);
+
+ std::vector<JID> blockedJIDs = clientBlockListManager_->getBlockList()->getItems();
+ CPPUNIT_ASSERT(blockedJIDs.end() == std::find(blockedJIDs.begin(), blockedJIDs.end(), JID("romeo@montague.net")));
+ }
+
+ void testUnblockAllCommand() {
+ // start with an already fetched block list
+ std::vector<JID> initialBlockList = std::vector<JID>(1, JID("iago@shakespeare.lit"));
+ initialBlockList.push_back(JID("romeo@montague.net"));
+ initialBlockList.push_back(JID("benvolio@montague.net"));
+ helperInitialBlockListFetch(initialBlockList);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), clientBlockListManager_->getBlockList()->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+
+ GenericRequest<UnblockPayload>::ref unblockRequest = clientBlockListManager_->createUnblockAllRequest();
+ unblockRequest->send();
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(2);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<UnblockPayload> unblockPayload = request->getPayload<UnblockPayload>();
+ CPPUNIT_ASSERT(unblockPayload.get() != NULL);
+ CPPUNIT_ASSERT_EQUAL(true, unblockPayload->getItems().empty());
+
+ IQ::ref unblockRequestResponse = IQ::createResult(request->getFrom(), JID(), request->getID());
+ stanzaChannel_->sendIQ(unblockRequestResponse);
+ stanzaChannel_->onIQReceived(unblockRequestResponse);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), clientBlockListManager_->getBlockList()->getItems().size());
+
+ // send block push
+ boost::shared_ptr<UnblockPayload> pushPayload = boost::make_shared<UnblockPayload>();
+ IQ::ref unblockPush = IQ::createRequest(IQ::Set, ownJID_, "push1", pushPayload);
+ stanzaChannel_->sendIQ(unblockPush);
+ stanzaChannel_->onIQReceived(unblockPush);
+
+ CPPUNIT_ASSERT_EQUAL(true, clientBlockListManager_->getBlockList()->getItems().empty());
+ }
+
+ void tearDown() {
+ delete clientBlockListManager_;
+ delete iqRouter_;
+ delete stanzaChannel_;
+ }
+
+ private:
+ void helperInitialBlockListFetch(const std::vector<JID>& blockedJids) {
+ boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ CPPUNIT_ASSERT(blockList);
+
+ // check for IQ request
+ IQ::ref request = stanzaChannel_->getStanzaAtIndex<IQ>(0);
+ CPPUNIT_ASSERT(request.get() != NULL);
+ boost::shared_ptr<BlockListPayload> requestPayload = request->getPayload<BlockListPayload>();
+ CPPUNIT_ASSERT(requestPayload.get() != NULL);
+
+ CPPUNIT_ASSERT_EQUAL(BlockList::Requesting, blockList->getState());
+ CPPUNIT_ASSERT_EQUAL(BlockList::Requesting, clientBlockListManager_->getBlockList()->getState());
+
+ // build IQ response
+ boost::shared_ptr<BlockListPayload> responsePayload = boost::make_shared<BlockListPayload>();
+ foreach(const JID& jid, blockedJids) {
+ responsePayload->addItem(jid);
+ }
+
+ IQ::ref response = IQ::createResult(ownJID_, JID(), request->getID(), responsePayload);
+ stanzaChannel_->sendIQ(response);
+ stanzaChannel_->onIQReceived(response);
+
+ CPPUNIT_ASSERT_EQUAL(BlockList::Available, clientBlockListManager_->getBlockList()->getState());
+ CPPUNIT_ASSERT(responsePayload->getItems() == clientBlockListManager_->getBlockList()->getItems());
+ }
+
+
+ private:
+ JID ownJID_;
+ IQRouter* iqRouter_;
+ DummyStanzaChannel* stanzaChannel_;
+ ClientBlockListManager* clientBlockListManager_;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ClientBlockListManagerTest);
+
diff --git a/Swiften/Elements/BlockListPayload.h b/Swiften/Elements/BlockListPayload.h
index 25cb602..49df75f 100644
--- a/Swiften/Elements/BlockListPayload.h
+++ b/Swiften/Elements/BlockListPayload.h
@@ -14,7 +14,7 @@
namespace Swift {
class BlockListPayload : public Payload {
public:
- BlockListPayload() {
+ BlockListPayload(const std::vector<JID>& items = std::vector<JID>()) : items(items) {
}
void addItem(const JID& item) {
diff --git a/Swiften/Elements/BlockPayload.h b/Swiften/Elements/BlockPayload.h
index 6dd5170..49a0463 100644
--- a/Swiften/Elements/BlockPayload.h
+++ b/Swiften/Elements/BlockPayload.h
@@ -14,7 +14,7 @@
namespace Swift {
class BlockPayload : public Payload {
public:
- BlockPayload() {
+ BlockPayload(const std::vector<JID>& jids = std::vector<JID>()) : items(jids) {
}
void addItem(const JID& jid) {
diff --git a/Swiften/Elements/DiscoInfo.cpp b/Swiften/Elements/DiscoInfo.cpp
index 1683916..f353c42 100644
--- a/Swiften/Elements/DiscoInfo.cpp
+++ b/Swiften/Elements/DiscoInfo.cpp
@@ -23,6 +23,7 @@ const std::string DiscoInfo::JingleTransportsS5BFeature = std::string("urn:xmpp:
const std::string DiscoInfo::Bytestream = std::string("http://jabber.org/protocol/bytestreams");
const std::string DiscoInfo::MessageDeliveryReceiptsFeature = std::string("urn:xmpp:receipts");
const std::string DiscoInfo::WhiteboardFeature = std::string("http://swift.im/whiteboard");
+const std::string DiscoInfo::BlockingCommandFeature = std::string("urn:xmpp:blocking");
bool DiscoInfo::Identity::operator<(const Identity& other) const {
if (category_ == other.category_) {
diff --git a/Swiften/Elements/DiscoInfo.h b/Swiften/Elements/DiscoInfo.h
index 3334ac8..3701096 100644
--- a/Swiften/Elements/DiscoInfo.h
+++ b/Swiften/Elements/DiscoInfo.h
@@ -34,6 +34,7 @@ namespace Swift {
static const std::string Bytestream;
static const std::string MessageDeliveryReceiptsFeature;
static const std::string WhiteboardFeature;
+ static const std::string BlockingCommandFeature;
class Identity {
public:
diff --git a/Swiften/Elements/UnblockPayload.h b/Swiften/Elements/UnblockPayload.h
index b6593ab..c5e7c80 100644
--- a/Swiften/Elements/UnblockPayload.h
+++ b/Swiften/Elements/UnblockPayload.h
@@ -14,7 +14,7 @@
namespace Swift {
class UnblockPayload : public Payload {
public:
- UnblockPayload() {
+ UnblockPayload(const std::vector<JID>& jids = std::vector<JID>()) : items(jids) {
}
void addItem(const JID& item) {
diff --git a/Swiften/Parser/PayloadParsers/BlockParser.h b/Swiften/Parser/PayloadParsers/BlockParser.h
index cd727ad..6ee47a2 100644
--- a/Swiften/Parser/PayloadParsers/BlockParser.h
+++ b/Swiften/Parser/PayloadParsers/BlockParser.h
@@ -7,13 +7,14 @@
#pragma once
#include <Swiften/Elements/Nickname.h>
+#include <Swiften/JID/JID.h>
#include <Swiften/Parser/GenericPayloadParser.h>
namespace Swift {
template<typename BLOCK_ELEMENT>
class BlockParser : public GenericPayloadParser<BLOCK_ELEMENT> {
public:
- BlockParser() : GenericPayloadParser<BLOCK_ELEMENT>() {
+ BlockParser() : GenericPayloadParser<BLOCK_ELEMENT>(), level(0) {
}
virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes) {
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/BlockParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/BlockParserTest.cpp
new file mode 100644
index 0000000..ddd3a88
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/UnitTest/BlockParserTest.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swiften/Parser/PayloadParsers/BlockParser.h>
+#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h>
+
+#include <Swiften/Elements/BlockPayload.h>
+#include <Swiften/Elements/UnblockPayload.h>
+#include <Swiften/Elements/BlockListPayload.h>
+
+using namespace Swift;
+
+class BlockParserTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(BlockParserTest);
+ CPPUNIT_TEST(testExample4);
+ CPPUNIT_TEST(testExample6);
+ CPPUNIT_TEST(testExample10);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ BlockParserTest() {}
+
+ void testExample4() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse("<blocklist xmlns='urn:xmpp:blocking'>"
+ "<item jid='romeo@montague.net'/>"
+ "<item jid='iago@shakespeare.lit'/>"
+ "</blocklist>"));
+
+ BlockListPayload* payload = dynamic_cast<BlockListPayload*>(parser.getPayload().get());
+ CPPUNIT_ASSERT(payload);
+ CPPUNIT_ASSERT(2 == payload->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), payload->getItems()[0]);
+ CPPUNIT_ASSERT_EQUAL(JID("iago@shakespeare.lit"), payload->getItems()[1]);
+ }
+
+ void testExample6() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse("<block xmlns='urn:xmpp:blocking'>"
+ "<item jid='romeo@montague.net'/>"
+ "</block>"));
+
+ BlockPayload* payload = dynamic_cast<BlockPayload*>(parser.getPayload().get());
+ CPPUNIT_ASSERT(payload);
+ CPPUNIT_ASSERT(1 == payload->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), payload->getItems()[0]);
+ }
+
+ void testExample10() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse("<unblock xmlns='urn:xmpp:blocking'>"
+ "<item jid='romeo@montague.net'/>"
+ "</unblock>"));
+
+ UnblockPayload* payload = dynamic_cast<UnblockPayload*>(parser.getPayload().get());
+ CPPUNIT_ASSERT(payload);
+ CPPUNIT_ASSERT(1 == payload->getItems().size());
+ CPPUNIT_ASSERT_EQUAL(JID("romeo@montague.net"), payload->getItems()[0]);
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BlockParserTest);
diff --git a/Swiften/Queries/GenericRequest.h b/Swiften/Queries/GenericRequest.h
index 68c86c5..b1b7f8a 100644
--- a/Swiften/Queries/GenericRequest.h
+++ b/Swiften/Queries/GenericRequest.h
@@ -22,6 +22,9 @@ namespace Swift {
template<typename PAYLOAD_TYPE>
class GenericRequest : public Request {
public:
+ typedef boost::shared_ptr<GenericRequest<PAYLOAD_TYPE> > ref;
+
+ public:
/**
* Create a request suitable for client use.
* @param type Iq type - Get or Set.
@@ -61,7 +64,7 @@ namespace Swift {
onResponse(boost::dynamic_pointer_cast<PAYLOAD_TYPE>(payload), error);
}
- protected:
+ public:
boost::shared_ptr<PAYLOAD_TYPE> getPayloadGeneric() const {
return boost::dynamic_pointer_cast<PAYLOAD_TYPE>(getPayload());
}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index a62d344..b9fad17 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -318,6 +318,7 @@ if env["SCONS_STAGE"] == "build" :
# File("Chat/UnitTest/ChatStateTrackerTest.cpp"),
File("Client/UnitTest/ClientSessionTest.cpp"),
File("Client/UnitTest/NickResolverTest.cpp"),
+ File("Client/UnitTest/ClientBlockListManagerTest.cpp"),
File("Compress/UnitTest/ZLibCompressorTest.cpp"),
File("Compress/UnitTest/ZLibDecompressorTest.cpp"),
File("Component/UnitTest/ComponentHandshakeGeneratorTest.cpp"),
@@ -347,6 +348,7 @@ if env["SCONS_STAGE"] == "build" :
File("Network/UnitTest/HTTPConnectProxiedConnectionTest.cpp"),
File("Network/UnitTest/BOSHConnectionTest.cpp"),
File("Network/UnitTest/BOSHConnectionPoolTest.cpp"),
+ File("Parser/PayloadParsers/UnitTest/BlockParserTest.cpp"),
File("Parser/PayloadParsers/UnitTest/BodyParserTest.cpp"),
File("Parser/PayloadParsers/UnitTest/DiscoInfoParserTest.cpp"),
File("Parser/PayloadParsers/UnitTest/DiscoItemsParserTest.cpp"),
@@ -401,6 +403,7 @@ if env["SCONS_STAGE"] == "build" :
File("Roster/UnitTest/XMPPRosterControllerTest.cpp"),
File("Roster/UnitTest/XMPPRosterSignalHandler.cpp"),
File("Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.cpp"),
+ File("Serializer/PayloadSerializers/UnitTest/BlockSerializerTest.cpp"),
File("Serializer/PayloadSerializers/UnitTest/CapsInfoSerializerTest.cpp"),
File("Serializer/PayloadSerializers/UnitTest/FormSerializerTest.cpp"),
File("Serializer/PayloadSerializers/UnitTest/DiscoInfoSerializerTest.cpp"),
diff --git a/Swiften/Serializer/PayloadSerializers/BlockSerializer.h b/Swiften/Serializer/PayloadSerializers/BlockSerializer.h
index 10ae8b0..fc628c2 100644
--- a/Swiften/Serializer/PayloadSerializers/BlockSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/BlockSerializer.h
@@ -8,6 +8,7 @@
#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/JID/JID.h>
#include <Swiften/Serializer/GenericPayloadSerializer.h>
#include <Swiften/Serializer/XML/XMLElement.h>
@@ -24,6 +25,7 @@ namespace Swift {
for (std::vector<JID>::const_iterator i = items.begin(); i != items.end(); ++i) {
boost::shared_ptr<XMLElement> item = boost::make_shared<XMLElement>("item");
item->setAttribute("jid", *i);
+ element.addNode(item);
}
return element.serialize();
}
diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/BlockSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/BlockSerializerTest.cpp
new file mode 100644
index 0000000..7772381
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/UnitTest/BlockSerializerTest.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2013 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swiften/Serializer/PayloadSerializers/BlockSerializer.h>
+#include <Swiften/Elements/BlockListPayload.h>
+#include <Swiften/Elements/BlockPayload.h>
+#include <Swiften/Elements/UnblockPayload.h>
+#include <Swiften/JID/JID.h>
+
+using namespace Swift;
+
+class BlockSerializerTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE(BlockSerializerTest);
+ CPPUNIT_TEST(testExample4);
+ CPPUNIT_TEST(testExample6);
+ CPPUNIT_TEST(testExample10);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ BlockSerializerTest() {}
+
+ void testExample4() {
+ BlockSerializer<BlockListPayload> testling("blocklist");
+ boost::shared_ptr<BlockListPayload> blocklist = boost::make_shared<BlockListPayload>();
+ blocklist->addItem(JID("romeo@montague.net"));
+ blocklist->addItem(JID("iago@shakespeare.lit"));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("<blocklist xmlns=\"urn:xmpp:blocking\"><item jid=\"romeo@montague.net\"/><item jid=\"iago@shakespeare.lit\"/></blocklist>"), testling.serialize(blocklist));
+ }
+
+ void testExample6() {
+ BlockSerializer<BlockPayload> testling("block");
+ boost::shared_ptr<BlockPayload> block = boost::make_shared<BlockPayload>();
+ block->addItem(JID("romeo@montague.net"));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("<block xmlns=\"urn:xmpp:blocking\"><item jid=\"romeo@montague.net\"/></block>"), testling.serialize(block));
+ }
+
+ void testExample10() {
+ BlockSerializer<UnblockPayload> testling("unblock");
+ boost::shared_ptr<UnblockPayload> unblock = boost::make_shared<UnblockPayload>();
+ unblock->addItem(JID("romeo@montague.net"));
+
+ CPPUNIT_ASSERT_EQUAL(std::string("<unblock xmlns=\"urn:xmpp:blocking\"><item jid=\"romeo@montague.net\"/></unblock>"), testling.serialize(unblock));
+ }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(BlockSerializerTest);