aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Vrátil <dvratil@kde.org>2016-09-07 12:51:03 (GMT)
committerDaniel Vrátil <dvratil@kde.org>2016-09-07 12:51:03 (GMT)
commitd9650a099ec5549a9cdc35c00278a16e0a75fd75 (patch)
treee48416dbb19e974dcedaa5a7abfce0e5521aac37
parent38216a7638281545b34892e8dca7d28764842fec (diff)
Add MoveHandlerTest, improve ItemMoveTest, minor MOVE fix
-rw-r--r--autotests/libs/itemmovetest.cpp44
-rw-r--r--autotests/server/CMakeLists.txt2
-rw-r--r--autotests/server/fakeakonadiserver.cpp8
-rw-r--r--autotests/server/fakeakonadiserver.h2
-rw-r--r--autotests/server/fakeitemretrievalmanager.cpp43
-rw-r--r--autotests/server/fakeitemretrievalmanager.h40
-rw-r--r--autotests/server/movehandlertest.cpp147
-rw-r--r--src/server/handler/move.cpp2
-rw-r--r--src/server/storage/itemretrievalmanager.h4
9 files changed, 282 insertions, 10 deletions
diff --git a/autotests/libs/itemmovetest.cpp b/autotests/libs/itemmovetest.cpp
index 3726266..2e2965b 100644
--- a/autotests/libs/itemmovetest.cpp
+++ b/autotests/libs/itemmovetest.cpp
@@ -24,6 +24,9 @@
#include "itemfetchjob.h"
#include "itemmovejob.h"
#include "itemfetchscope.h"
+#include "collectionfetchscope.h"
+#include "monitor.h"
+#include "session.h"
#include <QtCore/QObject>
@@ -49,17 +52,22 @@ private Q_SLOTS:
QTest::addColumn<Collection>("destination");
QTest::addColumn<Collection>("source");
- const Collection destination(collectionIdFromPath(QStringLiteral("res3")));
+ Collection destination(collectionIdFromPath(QStringLiteral("res1/foo/bar")));
QVERIFY(destination.isValid());
- QTest::newRow("single uid") << (Item::List() << Item(1)) << destination << Collection();
- QTest::newRow("two uid") << (Item::List() << Item(2) << Item(3)) << destination << Collection();
+ QTest::newRow("intra-res single uid") << (Item::List() << Item(5)) << destination << Collection();
+
+ destination = Collection(collectionIdFromPath(QStringLiteral("res3")));
+ QVERIFY(destination.isValid());
+
+ QTest::newRow("inter-res single uid") << (Item::List() << Item(1)) << destination << Collection();
+ QTest::newRow("inter-res two uid") << (Item::List() << Item(2) << Item(3)) << destination << Collection();
Item r1; r1.setRemoteId(QStringLiteral("D"));
Collection ridDest;
ridDest.setRemoteId(QStringLiteral("3"));
Collection ridSource;
ridSource.setRemoteId(QStringLiteral("10"));
- QTest::newRow("single rid") << (Item::List() << r1) << ridDest << ridSource;
+ QTest::newRow("intra-res single rid") << (Item::List() << r1) << ridDest << ridSource;
}
void testMove()
@@ -68,8 +76,15 @@ private Q_SLOTS:
QFETCH(Collection, destination);
QFETCH(Collection, source);
- //Collection source( collectionIdFromPath( "res1/foo" ) );
- //QVERIFY( source.isValid() );
+ Session monitorSession;
+ Monitor monitor(&monitorSession);
+ monitor.setObjectName(QStringLiteral("itemmovetest"));
+ monitor.setCollectionMonitored(Collection::root());
+ monitor.fetchCollection(true); monitor.itemFetchScope().setAncestorRetrieval(ItemFetchScope::Parent);
+ monitor.itemFetchScope().setFetchRemoteIdentification(true);
+ QSignalSpy moveSpy(&monitor, &Monitor::itemsMoved);
+ QSignalSpy readySpy(&monitor, &Monitor::monitorReady);
+ readySpy.wait();
ResourceSelectJob *select = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_0"));
AKVERIFYEXEC(select); // for rid based moves
@@ -82,12 +97,29 @@ private Q_SLOTS:
AKVERIFYEXEC(move);
ItemFetchJob *fetch = new ItemFetchJob(destination, this);
+ fetch->fetchScope().setAncestorRetrieval(ItemFetchScope::Parent);
fetch->fetchScope().fetchFullPayload();
AKVERIFYEXEC(fetch);
QCOMPARE(fetch->items().count(), items.count() + baseline);
foreach (const Item &movedItem, fetch->items()) {
QVERIFY(movedItem.hasPayload());
QVERIFY(!movedItem.payload<QByteArray>().isEmpty());
+ if (destination.id() >= 0) {
+ QCOMPARE(movedItem.parentCollection().id(), destination.id());
+ } else {
+ QCOMPARE(movedItem.parentCollection().remoteId(), destination.remoteId());
+ }
+ }
+
+ QTRY_COMPARE(moveSpy.count(), 1);
+ const Akonadi::Item::List &ntfItems = moveSpy.takeFirst().at(0).value<Akonadi::Item::List>();
+ QCOMPARE(ntfItems.size(), items.size());
+ Q_FOREACH (const Item &ntfItem, ntfItems) {
+ if (destination.id() >= 0) {
+ QCOMPARE(ntfItem.parentCollection().id(), destination.id());
+ } else {
+ QCOMPARE(ntfItem.parentCollection().remoteId(), destination.remoteId());
+ }
}
}
diff --git a/autotests/server/CMakeLists.txt b/autotests/server/CMakeLists.txt
index db51c41..78f99e6 100644
--- a/autotests/server/CMakeLists.txt
+++ b/autotests/server/CMakeLists.txt
@@ -30,6 +30,7 @@ set(common_SRCS
fakeclient.cpp
fakeakonadiserver.cpp
fakesearchmanager.cpp
+ fakeitemretrievalmanager.cpp
dbinitializer.cpp
${CMAKE_CURRENT_BINARY_DIR}/dbpopulator.cpp
)
@@ -92,6 +93,7 @@ add_server_test(akappendhandlertest.cpp)
add_server_test(linkhandlertest.cpp)
add_server_test(listhandlertest.cpp)
add_server_test(modifyhandlertest.cpp)
+add_server_test(movehandlertest.cpp)
add_server_test(createhandlertest.cpp)
add_server_test(collectionreferencetest.cpp)
add_server_test(searchtest.cpp akonadiprivate)
diff --git a/autotests/server/fakeakonadiserver.cpp b/autotests/server/fakeakonadiserver.cpp
index 9df989a..96417ea 100644
--- a/autotests/server/fakeakonadiserver.cpp
+++ b/autotests/server/fakeakonadiserver.cpp
@@ -22,6 +22,7 @@
#include "fakedatastore.h"
#include "fakesearchmanager.h"
#include "fakeclient.h"
+#include "fakeitemretrievalmanager.h"
#include <QSettings>
#include <QCoreApplication>
@@ -103,6 +104,10 @@ FakeAkonadiServer *FakeAkonadiServer::instance()
FakeAkonadiServer::FakeAkonadiServer()
: AkonadiServer()
, mDataStore(Q_NULLPTR)
+ , mSearchManager(Q_NULLPTR)
+ , mConnection(Q_NULLPTR)
+ , mClient(Q_NULLPTR)
+ , mRetrievalManager(Q_NULLPTR)
, mServerLoop(Q_NULLPTR)
, mNtfCollector(Q_NULLPTR)
, mPopulateDb(true)
@@ -120,6 +125,7 @@ FakeAkonadiServer::~FakeAkonadiServer()
{
delete mClient;
delete mConnection;
+ delete mRetrievalManager;
delete mNtfCollector;
}
@@ -216,6 +222,8 @@ bool FakeAkonadiServer::init()
PreprocessorManager::instance()->setEnabled(false);
mSearchManager = new FakeSearchManager();
+ mRetrievalManager = new FakeItemRetrievalManager();
+
const QString socketFile = basePath() + QLatin1String("/local/share/akonadi/akonadiserver.socket");
qDebug() << "==== Fake Akonadi Server started ====";
diff --git a/autotests/server/fakeakonadiserver.h b/autotests/server/fakeakonadiserver.h
index 49b4a45..d393dee 100644
--- a/autotests/server/fakeakonadiserver.h
+++ b/autotests/server/fakeakonadiserver.h
@@ -42,6 +42,7 @@ class FakeSearchManager;
class FakeDataStore;
class FakeConnection;
class FakeClient;
+class FakeItemRetrievalManager;
class TestScenario {
public:
@@ -122,6 +123,7 @@ private:
FakeSearchManager *mSearchManager;
FakeConnection *mConnection;
FakeClient *mClient;
+ FakeItemRetrievalManager *mRetrievalManager;
QEventLoop *mServerLoop;
diff --git a/autotests/server/fakeitemretrievalmanager.cpp b/autotests/server/fakeitemretrievalmanager.cpp
new file mode 100644
index 0000000..cbed3af
--- /dev/null
+++ b/autotests/server/fakeitemretrievalmanager.cpp
@@ -0,0 +1,43 @@
+/*
+ Copyright (c) 2016 Daniel Vrátil <dvratil@kde.org>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#include "fakeitemretrievalmanager.h"
+#include "storage/itemretrievalrequest.h"
+
+using namespace Akonadi::Server;
+
+FakeItemRetrievalManager::FakeItemRetrievalManager()
+ : ItemRetrievalManager()
+{
+ sInstance = this;
+
+ qRegisterMetaType<ItemRetrievalRequest*>("ItemRetrievalRequest*");
+}
+
+FakeItemRetrievalManager::~FakeItemRetrievalManager()
+{
+ sInstance = Q_NULLPTR;
+}
+
+void FakeItemRetrievalManager::requestItemDelivery(ItemRetrievalRequest *request)
+{
+ QMetaObject::invokeMethod(this, "requestFinished", Qt::QueuedConnection,
+ Q_ARG(ItemRetrievalRequest*, request));
+}
+
diff --git a/autotests/server/fakeitemretrievalmanager.h b/autotests/server/fakeitemretrievalmanager.h
new file mode 100644
index 0000000..1c8eb7a
--- /dev/null
+++ b/autotests/server/fakeitemretrievalmanager.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (c) 2016 Daniel Vrátil <dvratil@kde.org>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+
+#ifndef AKONADI_SERVER_FAKEITEMRETRIEVALMANAGER_H
+#define AKONADI_SERVER_FAKEITEMRETRIEVALMANAGER_H
+
+#include "storage/itemretrievalmanager.h"
+
+namespace Akonadi {
+namespace Server {
+
+class FakeItemRetrievalManager : public ItemRetrievalManager
+{
+ Q_OBJECT
+public:
+ explicit FakeItemRetrievalManager();
+ ~FakeItemRetrievalManager() Q_DECL_OVERRIDE;
+
+ void requestItemDelivery(ItemRetrievalRequest *request) Q_DECL_OVERRIDE;
+};
+
+} // namespace Server
+} // namespace Akonadi
+#endif
diff --git a/autotests/server/movehandlertest.cpp b/autotests/server/movehandlertest.cpp
new file mode 100644
index 0000000..22973cf
--- /dev/null
+++ b/autotests/server/movehandlertest.cpp
@@ -0,0 +1,147 @@
+/*
+ Copyright (c) 2016 Daniel Vrátil <dvratil@kde.org>
+
+ This library is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or (at your
+ option) any later version.
+
+ This library is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
+ License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
+*/
+#include <QObject>
+#include <handler/move.h>
+
+#include <storage/entity.h>
+
+#include "fakeakonadiserver.h"
+#include "aktest.h"
+#include "entities.h"
+
+#include <private/scope_p.h>
+#include <private/imapset_p.h>
+
+#include <QtTest/QTest>
+
+using namespace Akonadi;
+using namespace Akonadi::Server;
+
+Q_DECLARE_METATYPE(Akonadi::Protocol::ItemChangeNotification::List)
+Q_DECLARE_METATYPE(Akonadi::Protocol::ItemChangeNotification)
+
+class MoveHandlerTest : public QObject
+{
+ Q_OBJECT
+
+public:
+ MoveHandlerTest()
+ {
+ try {
+ FakeAkonadiServer::instance()->init();
+ } catch (const FakeAkonadiServerException &e) {
+ qWarning() << "Server exception: " << e.what();
+ qFatal("Fake Akonadi Server failed to start up, aborting test");
+ }
+ }
+
+ ~MoveHandlerTest()
+ {
+ FakeAkonadiServer::instance()->quit();
+ }
+
+private Q_SLOTS:
+ void testMove_data()
+ {
+ const Collection srcCol = Collection::retrieveByName(QStringLiteral("Collection B"));
+ const Collection destCol = Collection::retrieveByName(QStringLiteral("Collection A"));
+
+ QTest::addColumn<TestScenario::List>("scenarios");
+ QTest::addColumn<Protocol::ItemChangeNotification::List>("expectedNotifications");
+ QTest::addColumn<QVariant>("newValue");
+
+ Protocol::ItemChangeNotification notificationTemplate;
+ notificationTemplate.setOperation(Protocol::ItemChangeNotification::Move);
+ notificationTemplate.setResource("akonadi_fake_resource_0");
+ notificationTemplate.setDestinationResource("akonadi_fake_resource_0");
+ notificationTemplate.setSessionId(FakeAkonadiServer::instanceName().toLatin1());
+ notificationTemplate.setParentCollection(srcCol.id());
+ notificationTemplate.setParentDestCollection(destCol.id());
+
+ {
+ Protocol::MoveItemsCommand cmd(1, destCol.id());
+
+ TestScenario::List scenarios;
+ scenarios << FakeAkonadiServer::loginScenario()
+ << TestScenario::create(5, TestScenario::ClientCmd, cmd)
+ << TestScenario::create(5, TestScenario::ServerCmd, Protocol::MoveItemsResponse());
+
+ Protocol::ItemChangeNotification notification = notificationTemplate;
+ notification.setItem({ Protocol::ItemChangeNotification::Item(1, QStringLiteral("A"), QString(), QStringLiteral("application/octet-stream")) });
+
+ QTest::newRow("move item") << scenarios << Protocol::ItemChangeNotification::List{ notification }
+ << QVariant::fromValue(destCol.id());
+ }
+
+ {
+ Protocol::MoveItemsCommand cmd(QVector<qint64>{ 2, 3 }, destCol.id());
+
+ TestScenario::List scenarios;
+ scenarios << FakeAkonadiServer::loginScenario()
+ << TestScenario::create(5, TestScenario::ClientCmd, cmd)
+ << TestScenario::create(5, TestScenario::ServerCmd, Protocol::MoveItemsResponse());
+
+ Protocol::ItemChangeNotification notification = notificationTemplate;
+ notification.setItem({ Protocol::ItemChangeNotification::Item(2, QStringLiteral("B"), QString(), QStringLiteral("application/octet-stream")),
+ Protocol::ItemChangeNotification::Item(3, QStringLiteral("C"), QString(),
+ QStringLiteral("application/octet-stream")) });
+
+ QTest::newRow("mote items") << scenarios << Protocol::ItemChangeNotification::List{ notification }
+ << QVariant::fromValue(destCol.id());
+ }
+
+ }
+
+ void testMove()
+ {
+ QFETCH(TestScenario::List, scenarios);
+ QFETCH(Protocol::ItemChangeNotification::List, expectedNotifications);
+ QFETCH(QVariant, newValue);
+
+ FakeAkonadiServer::instance()->setScenarios(scenarios);
+ FakeAkonadiServer::instance()->runTest();
+
+ auto notificationSpy = FakeAkonadiServer::instance()->notificationSpy();
+ if (expectedNotifications.isEmpty()) {
+ QVERIFY(notificationSpy->isEmpty() || notificationSpy->takeFirst().first().value<Protocol::ChangeNotification::List>().isEmpty());
+ return;
+ }
+ QCOMPARE(notificationSpy->count(), 1);
+ //Only one notify call
+ QCOMPARE(notificationSpy->first().count(), 1);
+ const Protocol::ChangeNotification::List receivedNotifications = notificationSpy->first().first().value<Protocol::ChangeNotification::List>();
+ QCOMPARE(receivedNotifications.size(), expectedNotifications.count());
+
+ for (int i = 0; i < expectedNotifications.size(); i++) {
+ QCOMPARE(Protocol::ItemChangeNotification(receivedNotifications.at(i)), expectedNotifications.at(i));
+ Protocol::ItemChangeNotification notification = receivedNotifications.at(i);
+ QCOMPARE(notification.parentDestCollection(), newValue.toInt());
+
+ Q_FOREACH (const auto &ntfItem, notification.items()) {
+ const PimItem item = PimItem::retrieveById(ntfItem.id);
+ QCOMPARE(item.collectionId(), newValue.toInt());
+ }
+ }
+ }
+};
+
+AKTEST_FAKESERVER_MAIN(MoveHandlerTest)
+
+#include "movehandlertest.moc"
+
diff --git a/src/server/handler/move.cpp b/src/server/handler/move.cpp
index 90bdfd3..b63cf94 100644
--- a/src/server/handler/move.cpp
+++ b/src/server/handler/move.cpp
@@ -34,7 +34,6 @@ using namespace Akonadi::Server;
void Move::itemsRetrieved(const QList<qint64> &ids)
{
-
DataStore *store = connection()->storageBackend();
Transaction transaction(store);
@@ -51,7 +50,6 @@ void Move::itemsRetrieved(const QList<qint64> &ids)
const QVector<PimItem> items = qb.result();
if (items.isEmpty()) {
- successResponse<Protocol::MoveItemsResponse>();
return;
}
diff --git a/src/server/storage/itemretrievalmanager.h b/src/server/storage/itemretrievalmanager.h
index 529d550..ec8880f 100644
--- a/src/server/storage/itemretrievalmanager.h
+++ b/src/server/storage/itemretrievalmanager.h
@@ -62,7 +62,7 @@ public:
* Added for convenience. ItemRetrievalManager takes ownership over the
* pointer and deletes it when the request is processed.
*/
- void requestItemDelivery(ItemRetrievalRequest *request);
+ virtual void requestItemDelivery(ItemRetrievalRequest *request);
static ItemRetrievalManager *instance();
@@ -82,7 +82,7 @@ private Q_SLOTS:
void triggerCollectionTreeSync(const QString &resource);
void retrievalJobFinished(ItemRetrievalRequest *request, const QString &errorMsg);
-private:
+protected:
static ItemRetrievalManager *sInstance;
AbstractItemRetrievalJobFactory *mJobFactory;