File indexing completed on 2024-11-10 04:40:12

0001 /*
0002     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "collection.h"
0008 #include "collectionfetchscope.h"
0009 #include "control.h"
0010 #include "itemcreatejob.h"
0011 #include "itemfetchjob.h"
0012 #include "itemfetchscope.h"
0013 #include "itemmovejob.h"
0014 #include "monitor.h"
0015 #include "qtest_akonadi.h"
0016 #include "resourceselectjob_p.h"
0017 #include "session.h"
0018 
0019 #include <QObject>
0020 
0021 using namespace Akonadi;
0022 
0023 class ItemMoveTest : public QObject
0024 {
0025     Q_OBJECT
0026 private Q_SLOTS:
0027     void initTestCase()
0028     {
0029         AkonadiTest::checkTestIsIsolated();
0030         Control::start();
0031     }
0032 
0033     // TODO: test inter and intra resource moves
0034     void testMove_data()
0035     {
0036         QTest::addColumn<Item::List>("items");
0037         QTest::addColumn<Collection>("destination");
0038         QTest::addColumn<Collection>("source");
0039 
0040         Collection destination(AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo/bar")));
0041         QVERIFY(destination.isValid());
0042 
0043         QTest::newRow("intra-res single uid") << (Item::List() << Item(5)) << destination << Collection();
0044 
0045         destination = Collection(AkonadiTest::collectionIdFromPath(QStringLiteral("res3")));
0046         QVERIFY(destination.isValid());
0047 
0048         QTest::newRow("inter-res single uid") << (Item::List() << Item(1)) << destination << Collection();
0049         QTest::newRow("inter-res two uid") << (Item::List() << Item(2) << Item(3)) << destination << Collection();
0050         Item r1;
0051         r1.setRemoteId(QStringLiteral("D"));
0052         Collection ridDest;
0053         ridDest.setRemoteId(QStringLiteral("3"));
0054         Collection ridSource;
0055         ridSource.setRemoteId(QStringLiteral("10"));
0056         QTest::newRow("intra-res single rid") << (Item::List() << r1) << ridDest << ridSource;
0057     }
0058 
0059     void testMove()
0060     {
0061         QFETCH(Item::List, items);
0062         QFETCH(Collection, destination);
0063         QFETCH(Collection, source);
0064 
0065         Session monitorSession;
0066         Monitor monitor(&monitorSession);
0067         monitor.setObjectName(QLatin1StringView("itemmovetest"));
0068         monitor.setCollectionMonitored(Collection::root());
0069         monitor.fetchCollection(true);
0070         monitor.itemFetchScope().setAncestorRetrieval(ItemFetchScope::Parent);
0071         monitor.itemFetchScope().setFetchRemoteIdentification(true);
0072         QSignalSpy moveSpy(&monitor, &Monitor::itemsMoved);
0073         AkonadiTest::akWaitForSignal(&monitor, &Monitor::monitorReady);
0074 
0075         auto select = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_0"));
0076         AKVERIFYEXEC(select); // for rid based moves
0077 
0078         auto prefetchjob = new ItemFetchJob(destination, this);
0079         AKVERIFYEXEC(prefetchjob);
0080         int baseline = prefetchjob->items().size();
0081 
0082         auto move = new ItemMoveJob(items, source, destination, this);
0083         AKVERIFYEXEC(move);
0084 
0085         auto fetch = new ItemFetchJob(destination, this);
0086         fetch->fetchScope().setAncestorRetrieval(ItemFetchScope::Parent);
0087         fetch->fetchScope().fetchFullPayload();
0088         AKVERIFYEXEC(fetch);
0089         QCOMPARE(fetch->items().count(), items.count() + baseline);
0090         const Item::List movedItemList = fetch->items();
0091         for (const Item &movedItem : movedItemList) {
0092             QVERIFY(movedItem.hasPayload());
0093             QVERIFY(!movedItem.payload<QByteArray>().isEmpty());
0094             if (destination.id() >= 0) {
0095                 QCOMPARE(movedItem.parentCollection().id(), destination.id());
0096             } else {
0097                 QCOMPARE(movedItem.parentCollection().remoteId(), destination.remoteId());
0098             }
0099         }
0100 
0101         QTRY_COMPARE(moveSpy.count(), 1);
0102         const Akonadi::Item::List &ntfItems = moveSpy.takeFirst().at(0).value<Akonadi::Item::List>();
0103         QCOMPARE(ntfItems.size(), items.size());
0104         for (const Item &ntfItem : ntfItems) {
0105             if (destination.id() >= 0) {
0106                 QCOMPARE(ntfItem.parentCollection().id(), destination.id());
0107             } else {
0108                 QCOMPARE(ntfItem.parentCollection().remoteId(), destination.remoteId());
0109             }
0110         }
0111     }
0112 
0113     void testIllegalMove()
0114     {
0115         Collection col(AkonadiTest::collectionIdFromPath(QStringLiteral("res2")));
0116         QVERIFY(col.isValid());
0117 
0118         auto prefetchjob = new ItemFetchJob(Item(1));
0119         AKVERIFYEXEC(prefetchjob);
0120         QCOMPARE(prefetchjob->items().count(), 1);
0121         Item item = prefetchjob->items()[0];
0122 
0123         // move into invalid collection
0124         auto store = new ItemMoveJob(item, Collection(INT_MAX), this);
0125         QVERIFY(!store->exec());
0126 
0127         auto monitor = AkonadiTest::getTestMonitor();
0128         QSignalSpy itemMovedSpy(monitor.get(), &Monitor::itemsMoved);
0129 
0130         // move item into folder that doesn't support its mimetype
0131         store = new ItemMoveJob(item, col, this);
0132         QEXPECT_FAIL("", "Check not yet implemented by the server.", Continue);
0133         QVERIFY(!store->exec());
0134 
0135         // Wait for the notification so that it does not disturb the next test
0136         QTRY_COMPARE(itemMovedSpy.count(), 1);
0137     }
0138 
0139     void testMoveNotifications()
0140     {
0141         auto monitor = AkonadiTest::getTestMonitor();
0142         QSignalSpy itemMovedSpy(monitor.get(), &Monitor::itemsMoved);
0143         QSignalSpy itemAddedSpy(monitor.get(), &Monitor::itemAdded);
0144 
0145         Collection col(AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo")));
0146         Item item(QStringLiteral("application/octet-stream"));
0147         item.setFlags({"\\SEEN", "$ENCRYPTED"});
0148         item.setPayload(QByteArray("This is a test payload"));
0149         item.setSize(34);
0150         item.setParentCollection(col);
0151         auto create = new ItemCreateJob(item, col, this);
0152         AKVERIFYEXEC(create);
0153         item = create->item();
0154 
0155         QTRY_COMPARE(itemAddedSpy.size(), 1);
0156         auto ntfItem = itemAddedSpy.at(0).at(0).value<Akonadi::Item>();
0157         QCOMPARE(ntfItem.id(), item.id());
0158         QCOMPARE(ntfItem.flags(), item.flags());
0159 
0160         Collection dest(AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo/bar")));
0161         auto move = new ItemMoveJob(item, dest, this);
0162         AKVERIFYEXEC(move);
0163 
0164         QTRY_COMPARE(itemMovedSpy.size(), 1);
0165         const auto ntfItems = itemMovedSpy.at(0).at(0).value<Akonadi::Item::List>();
0166         QCOMPARE(ntfItems.size(), 1);
0167         ntfItem = ntfItems.at(0);
0168         QCOMPARE(ntfItem.id(), item.id());
0169         QCOMPARE(ntfItem.flags(), item.flags());
0170     }
0171 };
0172 
0173 QTEST_AKONADIMAIN(ItemMoveTest)
0174 
0175 #include "itemmovetest.moc"