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

0001 /*
0002     SPDX-FileCopyrightText: 2007 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "itemfetchtest.h"
0008 #include "attributefactory.h"
0009 #include "collectionpathresolver.h"
0010 #include "itemcreatejob.h"
0011 #include "itemdeletejob.h"
0012 #include "itemfetchjob.h"
0013 #include "itemfetchscope.h"
0014 #include "resourceselectjob_p.h"
0015 #include "testattribute.h"
0016 
0017 #include "qtest_akonadi.h"
0018 
0019 using namespace Akonadi;
0020 
0021 QTEST_AKONADIMAIN(ItemFetchTest)
0022 
0023 void ItemFetchTest::initTestCase()
0024 {
0025     AkonadiTest::checkTestIsIsolated();
0026     qRegisterMetaType<Akonadi::Item::List>();
0027     AttributeFactory::registerAttribute<TestAttribute>();
0028 }
0029 
0030 void ItemFetchTest::testFetch()
0031 {
0032     auto resolver = new CollectionPathResolver(QStringLiteral("res1"), this);
0033     AKVERIFYEXEC(resolver);
0034     int colId = resolver->collection();
0035 
0036     // listing of an empty folder
0037     auto job = new ItemFetchJob(Collection(colId), this);
0038     AKVERIFYEXEC(job);
0039     QVERIFY(job->items().isEmpty());
0040 
0041     resolver = new CollectionPathResolver(QStringLiteral("res1/foo"), this);
0042     AKVERIFYEXEC(resolver);
0043     int colId2 = resolver->collection();
0044 
0045     // listing of a non-empty folder
0046     job = new ItemFetchJob(Collection(colId2), this);
0047     QSignalSpy spy(job, &ItemFetchJob::itemsReceived);
0048     QVERIFY(spy.isValid());
0049     AKVERIFYEXEC(job);
0050     const Item::List items = job->items();
0051     QCOMPARE(items.count(), 15);
0052 
0053     int count = 0;
0054     for (int i = 0; i < spy.count(); ++i) {
0055         auto l = spy[i][0].value<Akonadi::Item::List>();
0056         for (int j = 0; j < l.count(); ++j) {
0057             QVERIFY(items.count() > count + j);
0058             QCOMPARE(items[count + j], l[j]);
0059         }
0060         count += l.count();
0061     }
0062     QCOMPARE(count, items.count());
0063 
0064     // check if the fetch response is parsed correctly (note: order is undefined)
0065     Item item;
0066     for (const Item &it : items) {
0067         if (it.remoteId() == QLatin1Char('A')) {
0068             item = it;
0069         }
0070     }
0071     QVERIFY(item.isValid());
0072 
0073     QCOMPARE(item.flags().count(), 3);
0074     QVERIFY(item.hasFlag("\\SEEN"));
0075     QVERIFY(item.hasFlag("\\FLAGGED"));
0076     QVERIFY(item.hasFlag("\\DRAFT"));
0077 
0078     item = Item();
0079     for (const Item &it : items) {
0080         if (it.remoteId() == QLatin1Char('B')) {
0081             item = it;
0082         }
0083     }
0084     QVERIFY(item.isValid());
0085     QCOMPARE(item.flags().count(), 1);
0086     QVERIFY(item.hasFlag("\\FLAGGED"));
0087 
0088     item = Item();
0089     for (const Item &it : items) {
0090         if (it.remoteId() == QLatin1Char('C')) {
0091             item = it;
0092         }
0093     }
0094     QVERIFY(item.isValid());
0095     QVERIFY(item.flags().isEmpty());
0096 }
0097 
0098 void ItemFetchTest::testResourceRetrieval()
0099 {
0100     Item item(1);
0101 
0102     auto job = new ItemFetchJob(item, this);
0103     job->fetchScope().fetchFullPayload(true);
0104     job->fetchScope().fetchAllAttributes(true);
0105     job->fetchScope().setCacheOnly(true);
0106     AKVERIFYEXEC(job);
0107     QCOMPARE(job->items().count(), 1);
0108     item = job->items().first();
0109     QCOMPARE(item.id(), 1LL);
0110     QVERIFY(!item.remoteId().isEmpty());
0111     QVERIFY(!item.hasPayload()); // not yet in cache
0112     QCOMPARE(item.attributes().count(), 1);
0113 
0114     job = new ItemFetchJob(item, this);
0115     job->fetchScope().fetchFullPayload(true);
0116     job->fetchScope().fetchAllAttributes(true);
0117     job->fetchScope().setCacheOnly(false);
0118     AKVERIFYEXEC(job);
0119     QCOMPARE(job->items().count(), 1);
0120     item = job->items().first();
0121     QCOMPARE(item.id(), 1LL);
0122     QVERIFY(!item.remoteId().isEmpty());
0123     QVERIFY(item.hasPayload());
0124     QCOMPARE(item.attributes().count(), 1);
0125 }
0126 
0127 void ItemFetchTest::testIllegalFetch()
0128 {
0129     // fetch non-existing folder
0130     auto job = new ItemFetchJob(Collection(INT_MAX), this);
0131     QVERIFY(!job->exec());
0132 
0133     // listing of root
0134     job = new ItemFetchJob(Collection::root(), this);
0135     QVERIFY(!job->exec());
0136 
0137     // fetch a non-existing message
0138     job = new ItemFetchJob(Item(INT_MAX), this);
0139     QVERIFY(!job->exec());
0140     QVERIFY(job->items().isEmpty());
0141 
0142     // fetch message with empty reference
0143     job = new ItemFetchJob(Item(), this);
0144     QVERIFY(!job->exec());
0145 }
0146 
0147 void ItemFetchTest::testMultipartFetch_data()
0148 {
0149     QTest::addColumn<bool>("fetchFullPayload");
0150     QTest::addColumn<bool>("fetchAllAttrs");
0151     QTest::addColumn<bool>("fetchSinglePayload");
0152     QTest::addColumn<bool>("fetchSingleAttr");
0153 
0154     QTest::newRow("empty") << false << false << false << false;
0155     QTest::newRow("full") << true << true << false << false;
0156     QTest::newRow("full payload") << true << false << false << false;
0157     QTest::newRow("single payload") << false << false << true << false;
0158     QTest::newRow("single") << false << false << true << true;
0159     QTest::newRow("attr full") << false << true << false << false;
0160     QTest::newRow("attr single") << false << false << false << true;
0161     QTest::newRow("mixed cross 1") << true << false << false << true;
0162     QTest::newRow("mixed cross 2") << false << true << true << false;
0163     QTest::newRow("all") << true << true << true << true;
0164     QTest::newRow("all payload") << true << false << true << false;
0165     QTest::newRow("all attr") << false << true << true << false;
0166 }
0167 
0168 void ItemFetchTest::testMultipartFetch()
0169 {
0170     QFETCH(bool, fetchFullPayload);
0171     QFETCH(bool, fetchAllAttrs);
0172     QFETCH(bool, fetchSinglePayload);
0173     QFETCH(bool, fetchSingleAttr);
0174 
0175     auto resolver = new CollectionPathResolver(QStringLiteral("res1/foo"), this);
0176     AKVERIFYEXEC(resolver);
0177     int colId = resolver->collection();
0178 
0179     Item item;
0180     item.setMimeType(QStringLiteral("application/octet-stream"));
0181     item.setPayload<QByteArray>("body data");
0182     item.attribute<TestAttribute>(Item::AddIfMissing)->data = "extra data";
0183     auto job = new ItemCreateJob(item, Collection(colId), this);
0184     AKVERIFYEXEC(job);
0185     Item ref = job->item();
0186 
0187     auto fjob = new ItemFetchJob(ref, this);
0188     fjob->setCollection(Collection(colId));
0189     if (fetchFullPayload) {
0190         fjob->fetchScope().fetchFullPayload();
0191     }
0192     if (fetchAllAttrs) {
0193         fjob->fetchScope().fetchAttribute<TestAttribute>();
0194     }
0195     if (fetchSinglePayload) {
0196         fjob->fetchScope().fetchPayloadPart(Item::FullPayload);
0197     }
0198     if (fetchSingleAttr) {
0199         fjob->fetchScope().fetchAttribute<TestAttribute>();
0200     }
0201 
0202     AKVERIFYEXEC(fjob);
0203     QCOMPARE(fjob->items().count(), 1);
0204     item = fjob->items().first();
0205 
0206     if (fetchFullPayload || fetchSinglePayload) {
0207         QCOMPARE(item.loadedPayloadParts().count(), 1);
0208         QVERIFY(item.hasPayload());
0209         QCOMPARE(item.payload<QByteArray>(), QByteArray("body data"));
0210     } else {
0211         QCOMPARE(item.loadedPayloadParts().count(), 0);
0212         QVERIFY(!item.hasPayload());
0213     }
0214 
0215     if (fetchAllAttrs || fetchSingleAttr) {
0216         QCOMPARE(item.attributes().count(), 1);
0217         QVERIFY(item.hasAttribute<TestAttribute>());
0218         QCOMPARE(item.attribute<TestAttribute>()->data, QByteArray("extra data"));
0219     } else {
0220         QCOMPARE(item.attributes().count(), 0);
0221     }
0222 
0223     // cleanup
0224     auto djob = new ItemDeleteJob(ref, this);
0225     AKVERIFYEXEC(djob);
0226 }
0227 
0228 void ItemFetchTest::testRidFetch()
0229 {
0230     Item item;
0231     item.setRemoteId(QStringLiteral("A"));
0232     Collection col;
0233     col.setRemoteId(QStringLiteral("10"));
0234 
0235     auto select = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_0"), this);
0236     AKVERIFYEXEC(select);
0237 
0238     auto job = new ItemFetchJob(item, this);
0239     job->setCollection(col);
0240     AKVERIFYEXEC(job);
0241     QCOMPARE(job->items().count(), 1);
0242     item = job->items().first();
0243     QVERIFY(item.isValid());
0244     QCOMPARE(item.remoteId(), QString::fromLatin1("A"));
0245     QCOMPARE(item.mimeType(), QString::fromLatin1("application/octet-stream"));
0246 }
0247 
0248 void ItemFetchTest::testAncestorRetrieval()
0249 {
0250     auto job = new ItemFetchJob(Item(1), this);
0251     job->fetchScope().setAncestorRetrieval(ItemFetchScope::All);
0252     AKVERIFYEXEC(job);
0253     QCOMPARE(job->items().count(), 1);
0254     const Item item = job->items().first();
0255     QVERIFY(item.isValid());
0256     QCOMPARE(item.remoteId(), QString::fromLatin1("A"));
0257     QCOMPARE(item.mimeType(), QString::fromLatin1("application/octet-stream"));
0258     const Collection c = item.parentCollection();
0259     QCOMPARE(c.remoteId(), QLatin1StringView("10"));
0260     const Collection c2 = c.parentCollection();
0261     QCOMPARE(c2.remoteId(), QLatin1StringView("6"));
0262     const Collection c3 = c2.parentCollection();
0263     QCOMPARE(c3, Collection::root());
0264 }
0265 
0266 #include "moc_itemfetchtest.cpp"