File indexing completed on 2024-12-22 04:57:37
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> 0003 SPDX-FileContributor: Kevin Krammer <krake@kdab.com> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "mixedmaildirresource_debug.h" 0009 #include "mixedmaildirstore.h" 0010 #include "testdatautil.h" 0011 0012 #include "filestore/itemcreatejob.h" 0013 #include "filestore/itemfetchjob.h" 0014 0015 #include "libmaildir/maildir.h" 0016 0017 #include <KMbox/MBox> 0018 0019 #include <Akonadi/MessageParts> 0020 0021 #include <Akonadi/ItemFetchScope> 0022 0023 #include <KRandom> 0024 #include <KRandomSequence> 0025 #include <QTemporaryDir> 0026 0027 #include <QSignalSpy> 0028 0029 #include <QDir> 0030 #include <QFileInfo> 0031 #include <QTest> 0032 using namespace Akonadi; 0033 using namespace KMBox; 0034 0035 static Item::List itemsFromSpy(QSignalSpy *spy) 0036 { 0037 Item::List items; 0038 0039 QListIterator<QList<QVariant>> it(*spy); 0040 while (it.hasNext()) { 0041 const QList<QVariant> invocation = it.next(); 0042 Q_ASSERT(invocation.count() == 1); 0043 0044 items << invocation.first().value<Item::List>(); 0045 } 0046 0047 return items; 0048 } 0049 0050 // copied from mail serializer plugin, SPDX-FileCopyrightText: 2007 Till Adam <adam@kde.org> 0051 static QSet<QByteArray> messageParts(const KMime::Message::Ptr &msgPtr) 0052 { 0053 QSet<QByteArray> set; 0054 // FIXME: we actually want "has any header" here, but the kmime api doesn't offer that yet 0055 if (msgPtr->hasContent() || msgPtr->hasHeader("Message-ID")) { 0056 set << MessagePart::Envelope << MessagePart::Header; 0057 if (!msgPtr->body().isEmpty() || !msgPtr->contents().isEmpty()) { 0058 set << MessagePart::Body; 0059 } 0060 } 0061 return set; 0062 } 0063 0064 // needed to sort maildir directory entries by filename which is their 0065 // remoteId. tagListHash.contains tests below need sorting of entries. 0066 static bool itemLessThanByRemoteId(const Item &item1, const Item &item2) 0067 { 0068 return item1.remoteId() < item2.remoteId(); 0069 } 0070 0071 class ItemFetchTest : public QObject 0072 { 0073 Q_OBJECT 0074 0075 public: 0076 ItemFetchTest() 0077 : QObject() 0078 , mStore(0) 0079 , mDir(0) 0080 , mIndexFilePattern(QLatin1StringView(".%1.index")) 0081 { 0082 // for monitoring signals 0083 qRegisterMetaType<Akonadi::Collection::List>(); 0084 qRegisterMetaType<Akonadi::Item::List>(); 0085 } 0086 0087 ~ItemFetchTest() 0088 { 0089 delete mStore; 0090 delete mDir; 0091 } 0092 0093 QString indexFile(const QString &folder) const 0094 { 0095 return mIndexFilePattern.arg(folder); 0096 } 0097 0098 QString indexFile(const QFileInfo &folderFileInfo) const 0099 { 0100 return QFileInfo(folderFileInfo.absolutePath(), mIndexFilePattern.arg(folderFileInfo.fileName())).absoluteFilePath(); 0101 } 0102 0103 private: 0104 MixedMaildirStore *mStore; 0105 QTemporaryDir *mDir; 0106 0107 const QString mIndexFilePattern; 0108 0109 private Q_SLOTS: 0110 void init(); 0111 void cleanup(); 0112 void testListingMaildir(); 0113 void testListingMBox(); 0114 void testSingleItemFetchMaildir(); 0115 void testSingleItemFetchMBox(); 0116 }; 0117 0118 void ItemFetchTest::init() 0119 { 0120 mStore = new MixedMaildirStore; 0121 0122 mDir = new QTemporaryDir; 0123 QVERIFY(mDir->isValid()); 0124 QVERIFY(QDir(mDir->path()).exists()); 0125 } 0126 0127 void ItemFetchTest::cleanup() 0128 { 0129 delete mStore; 0130 mStore = 0; 0131 delete mDir; 0132 mDir = 0; 0133 } 0134 0135 void ItemFetchTest::testListingMaildir() 0136 { 0137 QDir topDir(mDir->path()); 0138 0139 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("maildir"), topDir.path(), QLatin1StringView("collection1"))); 0140 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("maildir"), topDir.path(), QLatin1StringView("collection2"))); 0141 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("maildir-tagged"), topDir.path(), QLatin1StringView("collection3"))); 0142 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("dimap"), topDir.path(), QLatin1StringView("collection4"))); 0143 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("maildir-tagged"), topDir.path(), QLatin1StringView("collection5"))); 0144 0145 KPIM::Maildir topLevelMd(topDir.path(), true); 0146 0147 KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1StringView("collection1")); 0148 const QStringList md1EntryList = md1.entryList(); 0149 QSet<QString> entrySet1(md1EntryList.cbegin().md1EntryList.cend()); 0150 QCOMPARE((int)entrySet1.count(), 4); 0151 0152 QFileInfo indexFileInfo1(indexFile(QFileInfo(md1.path()))); 0153 QVERIFY(QFile::remove(indexFileInfo1.absoluteFilePath())); 0154 0155 KPIM::Maildir md2 = topLevelMd.subFolder(QLatin1StringView("collection2")); 0156 const QStringList md2EntryList = md2.entryList(); 0157 QSet<QString> entrySet2(md2EntryList.cbegin(), md2EntryList.cend()); 0158 QCOMPARE((int)entrySet2.count(), 4); 0159 0160 KPIM::Maildir md3 = topLevelMd.subFolder(QLatin1StringView("collection3")); 0161 const QStringList md3EntryList = md3.entryList(); 0162 QSet<QString> entrySet3(md3EntryList.cbegin(), md3EntryList.cend()); 0163 QCOMPARE((int)entrySet3.count(), 4); 0164 0165 KPIM::Maildir md4 = topLevelMd.subFolder(QLatin1StringView("collection4")); 0166 const QStringList md4EntryList = md4.entryList(); 0167 QSet<QString> entrySet4(md4EntryList.cbegin(), md4EntryList.cend()); 0168 QCOMPARE((int)entrySet4.count(), 4); 0169 0170 KPIM::Maildir md5 = topLevelMd.subFolder(QLatin1StringView("collection5")); 0171 const QStringList md5EntryList = md5.entryList(); 0172 QSet<QString> entrySet5(md5EntryList.cbegin(), md5EntryList.cend()); 0173 QCOMPARE((int)entrySet5.count(), 4); 0174 0175 mStore->setPath(topDir.path()); 0176 0177 // common variables 0178 FileStore::ItemFetchJob *job = 0; 0179 0180 QSignalSpy *spy = 0; 0181 Item::List items; 0182 0183 QHash<QString, QVariant> uidHash; 0184 const QVariant varUidHash = QVariant::fromValue<QHash<QString, QVariant>>(uidHash); 0185 QHash<QString, QVariant> tagListHash; 0186 const QVariant varTagListHash = QVariant::fromValue<QHash<QString, QVariant>>(tagListHash); 0187 QVariant var; 0188 0189 QSet<QString> entrySet; 0190 QMap<QByteArray, int> flagCounts; 0191 0192 // test listing maildir without index 0193 Collection collection1; 0194 collection1.setName(QLatin1StringView("collection1")); 0195 collection1.setRemoteId(QLatin1StringView("collection1")); 0196 collection1.setParentCollection(mStore->topLevelCollection()); 0197 0198 job = mStore->fetchItems(collection1); 0199 0200 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0201 0202 QVERIFY(job->exec()); 0203 QCOMPARE(job->error(), 0); 0204 0205 items = job->items(); 0206 QCOMPARE((int)items.count(), 4); 0207 QCOMPARE(itemsFromSpy(spy), items); 0208 0209 entrySet = entrySet1; 0210 QVERIFY(entrySet.remove(items[0].remoteId())); 0211 QVERIFY(entrySet.remove(items[1].remoteId())); 0212 QVERIFY(entrySet.remove(items[2].remoteId())); 0213 QVERIFY(entrySet.remove(items[3].remoteId())); 0214 0215 QCOMPARE(items[0].parentCollection(), collection1); 0216 QCOMPARE(items[1].parentCollection(), collection1); 0217 QCOMPARE(items[2].parentCollection(), collection1); 0218 QCOMPARE(items[3].parentCollection(), collection1); 0219 0220 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0221 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0222 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0223 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0224 0225 for (const Item &item : std::as_const(items)) { 0226 const auto flags{item.flags()}; 0227 for (const QByteArray &flag : flags) { 0228 ++flagCounts[flag]; 0229 } 0230 } 0231 0232 // no flags from maildir file name, no advanced flags without index 0233 QCOMPARE(flagCounts.count(), 0); 0234 QCOMPARE(flagCounts["\\SEEN"], 0); 0235 QCOMPARE(flagCounts["\\FLAGGED"], 0); 0236 QCOMPARE(flagCounts["$TODO"], 0); 0237 flagCounts.clear(); 0238 0239 var = job->property("remoteIdToTagList"); 0240 QVERIFY(!var.isValid()); 0241 0242 // test listing empty mbox without index 0243 for (const QString &entry, std::as_const(entrySet1)) { 0244 QVERIFY(md1.removeEntry(entry)); 0245 } 0246 QCOMPARE(md1.entryList().count(), 0); 0247 0248 job = mStore->fetchItems(collection1); 0249 0250 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0251 0252 QVERIFY(job->exec()); 0253 QCOMPARE(job->error(), 0); 0254 0255 items = job->items(); 0256 QCOMPARE((int)items.count(), 0); 0257 QCOMPARE(spy->count(), 0); 0258 0259 var = job->property("remoteIdToTagList"); 0260 QVERIFY(!var.isValid()); 0261 0262 // test listing maildir with index 0263 Collection collection2; 0264 collection2.setName(QLatin1StringView("collection2")); 0265 collection2.setRemoteId(QLatin1StringView("collection2")); 0266 collection2.setParentCollection(mStore->topLevelCollection()); 0267 0268 job = mStore->fetchItems(collection2); 0269 0270 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0271 0272 QVERIFY(job->exec()); 0273 QCOMPARE(job->error(), 0); 0274 0275 items = job->items(); 0276 QCOMPARE((int)items.count(), 4); 0277 QCOMPARE(itemsFromSpy(spy), items); 0278 0279 entrySet = entrySet2; 0280 QVERIFY(entrySet.remove(items[0].remoteId())); 0281 QVERIFY(entrySet.remove(items[1].remoteId())); 0282 QVERIFY(entrySet.remove(items[2].remoteId())); 0283 QVERIFY(entrySet.remove(items[3].remoteId())); 0284 0285 QCOMPARE(items[0].parentCollection(), collection2); 0286 QCOMPARE(items[1].parentCollection(), collection2); 0287 QCOMPARE(items[2].parentCollection(), collection2); 0288 QCOMPARE(items[3].parentCollection(), collection2); 0289 0290 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0291 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0292 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0293 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0294 0295 // see data/README 0296 for (const Item &item : std::as_const(items)) { 0297 const auto flags{item.flags()}; 0298 for (const QByteArray &flag : flags) { 0299 ++flagCounts[flag]; 0300 } 0301 } 0302 QCOMPARE(flagCounts["\\SEEN"], 2); 0303 QCOMPARE(flagCounts["\\FLAGGED"], 1); 0304 QCOMPARE(flagCounts["$TODO"], 1); 0305 flagCounts.clear(); 0306 0307 var = job->property("remoteIdToTagList"); 0308 QVERIFY(!var.isValid()); 0309 0310 // test listing empty maildir with index 0311 for (const QString &entry : std::as_const(entrySet2)) { 0312 QVERIFY(md2.removeEntry(entry)); 0313 } 0314 QCOMPARE(md2.entryList().count(), 0); 0315 0316 job = mStore->fetchItems(collection2); 0317 0318 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0319 0320 QVERIFY(job->exec()); 0321 QCOMPARE(job->error(), 0); 0322 0323 items = job->items(); 0324 QCOMPARE((int)items.count(), 0); 0325 QCOMPARE(spy->count(), 0); 0326 0327 var = job->property("remoteIdToTagList"); 0328 QVERIFY(!var.isValid()); 0329 0330 // test listing maildir with index which has tags 0331 Collection collection3; 0332 collection3.setName(QLatin1StringView("collection3")); 0333 collection3.setRemoteId(QLatin1StringView("collection3")); 0334 collection3.setParentCollection(mStore->topLevelCollection()); 0335 0336 job = mStore->fetchItems(collection3); 0337 0338 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0339 0340 QVERIFY(job->exec()); 0341 QCOMPARE(job->error(), 0); 0342 0343 items = job->items(); 0344 QCOMPARE((int)items.count(), 4); 0345 QCOMPARE(itemsFromSpy(spy), items); 0346 0347 entrySet = entrySet3; 0348 QVERIFY(entrySet.remove(items[0].remoteId())); 0349 QVERIFY(entrySet.remove(items[1].remoteId())); 0350 QVERIFY(entrySet.remove(items[2].remoteId())); 0351 QVERIFY(entrySet.remove(items[3].remoteId())); 0352 0353 QCOMPARE(items[0].parentCollection(), collection3); 0354 QCOMPARE(items[1].parentCollection(), collection3); 0355 QCOMPARE(items[2].parentCollection(), collection3); 0356 QCOMPARE(items[3].parentCollection(), collection3); 0357 0358 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0359 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0360 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0361 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0362 0363 // see data/README 0364 for (const Item &item : std::as_const(items)) { 0365 const auto flags{item.flags()}; 0366 for (const QByteArray &flag : flags) { 0367 ++flagCounts[flag]; 0368 } 0369 } 0370 0371 // 2x \SEEN flags: 2x from index, none from file name 0372 QCOMPARE(flagCounts["\\SEEN"], 2); 0373 QCOMPARE(flagCounts["\\FLAGGED"], 1); 0374 QCOMPARE(flagCounts["$TODO"], 1); 0375 flagCounts.clear(); 0376 0377 var = job->property("remoteIdToTagList"); 0378 QVERIFY(var.isValid()); 0379 0380 // tagListHash.contains tests below needs sorting of entries, 0381 // but libmaildir does not sort for performance reasons. 0382 // TODO: Check should not depend on any specific ordering. 0383 qSort(items.begin(), items.end(), itemLessThanByRemoteId); 0384 0385 tagListHash = var.value<QHash<QString, QVariant>>(); 0386 QCOMPARE((int)tagListHash.count(), 3); 0387 QVERIFY(!tagListHash.contains(items[0].remoteId())); 0388 QVERIFY(!tagListHash.value(items[1].remoteId()).toString().isEmpty()); 0389 QVERIFY(!tagListHash.value(items[2].remoteId()).toString().isEmpty()); 0390 QVERIFY(!tagListHash.value(items[3].remoteId()).toString().isEmpty()); 0391 0392 // test listing maildir with index which contains IMAP UIDs (dimap cache directory) 0393 Collection collection4; 0394 collection4.setName(QLatin1StringView("collection4")); 0395 collection4.setRemoteId(QLatin1StringView("collection4")); 0396 collection4.setParentCollection(mStore->topLevelCollection()); 0397 0398 job = mStore->fetchItems(collection4); 0399 0400 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0401 0402 QVERIFY(job->exec()); 0403 QCOMPARE(job->error(), 0); 0404 0405 items = job->items(); 0406 QCOMPARE((int)items.count(), 4); 0407 QCOMPARE(itemsFromSpy(spy), items); 0408 0409 entrySet = entrySet4; 0410 QVERIFY(entrySet.remove(items[0].remoteId())); 0411 QVERIFY(entrySet.remove(items[1].remoteId())); 0412 QVERIFY(entrySet.remove(items[2].remoteId())); 0413 QVERIFY(entrySet.remove(items[3].remoteId())); 0414 0415 QCOMPARE(items[0].parentCollection(), collection4); 0416 QCOMPARE(items[1].parentCollection(), collection4); 0417 QCOMPARE(items[2].parentCollection(), collection4); 0418 QCOMPARE(items[3].parentCollection(), collection4); 0419 0420 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0421 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0422 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0423 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0424 0425 // see data/README 0426 for (const Item &item : std::as_const(items)) { 0427 const auto flags{item.flags()}; 0428 for (const QByteArray &flag : flags) { 0429 ++flagCounts[flag]; 0430 } 0431 } 0432 QCOMPARE(flagCounts["\\SEEN"], 2); 0433 QCOMPARE(flagCounts["\\FLAGGED"], 1); 0434 QCOMPARE(flagCounts["$TODO"], 1); 0435 flagCounts.clear(); 0436 0437 var = job->property("remoteIdToTagList"); 0438 QVERIFY(!var.isValid()); 0439 0440 var = job->property("remoteIdToIndexUid"); 0441 QVERIFY(var.isValid()); 0442 0443 uidHash = var.value<QHash<QString, QVariant>>(); 0444 QCOMPARE((int)uidHash.count(), 4); 0445 bool ok = false; 0446 QVERIFY(!uidHash.value(items[0].remoteId()).toString().toInt(&ok) >= 0 && ok); 0447 QVERIFY(!uidHash.value(items[1].remoteId()).toString().toInt(&ok) >= 0 && ok); 0448 QVERIFY(!uidHash.value(items[2].remoteId()).toString().toInt(&ok) >= 0 && ok); 0449 QVERIFY(!uidHash.value(items[3].remoteId()).toString().toInt(&ok) >= 0 && ok); 0450 0451 // test listing maildir with index but newer modification date than index's one 0452 const QByteArray data5 = md5.readEntry(*entrySet5.cbegin()); 0453 QVERIFY(!data5.isEmpty()); 0454 0455 QTest::qSleep(1000); 0456 0457 QString newRemoteId = md5.addEntry(data5); 0458 QVERIFY(!newRemoteId.isEmpty()); 0459 0460 const QStringList md5EntryList = md5.entryList(); 0461 entrySet = QSet<QString>(md5EntryList.cbegin(), md5EntryList.cend()); 0462 entrySet.remove(newRemoteId); 0463 QCOMPARE(entrySet, entrySet5); 0464 QFileInfo fileInfo5(md5.path(), QLatin1StringView("new")); 0465 QFileInfo indexFileInfo5 = indexFile(QFileInfo(md5.path())); 0466 QVERIFY(fileInfo5.lastModified() > indexFileInfo5.lastModified()); 0467 0468 Collection collection5; 0469 collection5.setName(QLatin1StringView("collection5")); 0470 collection5.setRemoteId(QLatin1StringView("collection5")); 0471 collection5.setParentCollection(mStore->topLevelCollection()); 0472 0473 job = mStore->fetchItems(collection5); 0474 0475 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0476 0477 QVERIFY(job->exec()); 0478 QCOMPARE(job->error(), 0); 0479 0480 items = job->items(); 0481 QCOMPARE((int)items.count(), 5); 0482 QCOMPARE(itemsFromSpy(spy), items); 0483 0484 entrySet = entrySet5; 0485 entrySet << newRemoteId; 0486 QVERIFY(entrySet.remove(items[0].remoteId())); 0487 QVERIFY(entrySet.remove(items[1].remoteId())); 0488 QVERIFY(entrySet.remove(items[2].remoteId())); 0489 QVERIFY(entrySet.remove(items[3].remoteId())); 0490 QVERIFY(entrySet.remove(items[4].remoteId())); 0491 0492 QCOMPARE(items[0].parentCollection(), collection5); 0493 QCOMPARE(items[1].parentCollection(), collection5); 0494 QCOMPARE(items[2].parentCollection(), collection5); 0495 QCOMPARE(items[3].parentCollection(), collection5); 0496 QCOMPARE(items[4].parentCollection(), collection5); 0497 0498 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0499 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0500 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0501 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0502 QVERIFY(!items[4].hasPayload<KMime::Message::Ptr>()); 0503 0504 // not flags from index, no flags from file names 0505 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0506 QCOMPARE(items[1].flags(), QSet<QByteArray>()); 0507 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0508 QCOMPARE(items[3].flags(), QSet<QByteArray>()); 0509 QCOMPARE(items[4].flags(), QSet<QByteArray>()); 0510 0511 var = job->property("remoteIdToTagList"); 0512 QVERIFY(!var.isValid()); 0513 } 0514 0515 void ItemFetchTest::testListingMBox() 0516 { 0517 QDir topDir(mDir->path()); 0518 0519 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox"), topDir.path(), QLatin1StringView("collection1"))); 0520 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox"), topDir.path(), QLatin1StringView("collection2"))); 0521 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox-tagged"), topDir.path(), QLatin1StringView("collection3"))); 0522 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox-unpurged"), topDir.path(), QLatin1StringView("collection4"))); 0523 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox-tagged"), topDir.path(), QLatin1StringView("collection5"))); 0524 0525 QFileInfo fileInfo1(topDir.path(), QLatin1StringView("collection1")); 0526 MBox mbox1; 0527 QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); 0528 MBoxEntry::List entryList1 = mbox1.entries(); 0529 QCOMPARE((int)entryList1.count(), 4); 0530 0531 QFileInfo indexFileInfo1 = indexFile(fileInfo1); 0532 QVERIFY(QFile::remove(indexFileInfo1.absoluteFilePath())); 0533 0534 QFileInfo fileInfo2(topDir.path(), QLatin1StringView("collection2")); 0535 MBox mbox2; 0536 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0537 MBoxEntry::List entryList2 = mbox2.entries(); 0538 QCOMPARE((int)entryList2.count(), 4); 0539 0540 QFileInfo fileInfo3(topDir.path(), QLatin1StringView("collection3")); 0541 MBox mbox3; 0542 QVERIFY(mbox3.load(fileInfo3.absoluteFilePath())); 0543 MBoxEntry::List entryList3 = mbox3.entries(); 0544 QCOMPARE((int)entryList3.count(), 4); 0545 0546 QFileInfo fileInfo4(topDir.path(), QLatin1StringView("collection4")); 0547 MBox mbox4; 0548 QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); 0549 MBoxEntry::List entryList4 = mbox4.entries(); 0550 QCOMPARE((int)entryList4.count(), 4); 0551 0552 QFileInfo fileInfo5(topDir.path(), QLatin1StringView("collection5")); 0553 MBox mbox5; 0554 QVERIFY(mbox5.load(fileInfo5.absoluteFilePath())); 0555 MBoxEntry::List entryList5 = mbox5.entries(); 0556 QCOMPARE((int)entryList5.count(), 4); 0557 0558 mStore->setPath(topDir.path()); 0559 0560 // common variables 0561 FileStore::ItemFetchJob *job = 0; 0562 0563 QSignalSpy *spy = 0; 0564 Item::List items; 0565 0566 QHash<QString, QVariant> tagListHash; 0567 const QVariant varTagListHash = QVariant::fromValue<QHash<QString, QVariant>>(tagListHash); 0568 QVariant var; 0569 0570 // test listing mbox without index 0571 Collection collection1; 0572 collection1.setName(QLatin1StringView("collection1")); 0573 collection1.setRemoteId(QLatin1StringView("collection1")); 0574 collection1.setParentCollection(mStore->topLevelCollection()); 0575 0576 job = mStore->fetchItems(collection1); 0577 0578 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0579 0580 QVERIFY(job->exec()); 0581 QCOMPARE(job->error(), 0); 0582 0583 items = job->items(); 0584 QCOMPARE((int)items.count(), 4); 0585 QCOMPARE(itemsFromSpy(spy), items); 0586 0587 QCOMPARE(items[0].remoteId(), QString::number(entryList1[0].messageOffset())); 0588 QCOMPARE(items[1].remoteId(), QString::number(entryList1[1].messageOffset())); 0589 QCOMPARE(items[2].remoteId(), QString::number(entryList1[2].messageOffset())); 0590 QCOMPARE(items[3].remoteId(), QString::number(entryList1[3].messageOffset())); 0591 0592 QCOMPARE(items[0].parentCollection(), collection1); 0593 QCOMPARE(items[1].parentCollection(), collection1); 0594 QCOMPARE(items[2].parentCollection(), collection1); 0595 QCOMPARE(items[3].parentCollection(), collection1); 0596 0597 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0598 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0599 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0600 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0601 0602 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0603 QCOMPARE(items[1].flags(), QSet<QByteArray>()); 0604 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0605 QCOMPARE(items[3].flags(), QSet<QByteArray>()); 0606 0607 var = job->property("remoteIdToTagList"); 0608 QVERIFY(!var.isValid()); 0609 0610 // test listing empty mbox without index 0611 QFile file1(fileInfo1.absoluteFilePath()); 0612 QVERIFY(file1.open(QIODevice::WriteOnly | QIODevice::Truncate)); 0613 file1.close(); 0614 QCOMPARE((int)file1.size(), 0); 0615 0616 job = mStore->fetchItems(collection1); 0617 0618 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0619 0620 QVERIFY(job->exec()); 0621 QCOMPARE(job->error(), 0); 0622 0623 items = job->items(); 0624 QCOMPARE((int)items.count(), 0); 0625 QCOMPARE(spy->count(), 0); 0626 0627 var = job->property("remoteIdToTagList"); 0628 QVERIFY(!var.isValid()); 0629 0630 // test listing mbox with index 0631 Collection collection2; 0632 collection2.setName(QLatin1StringView("collection2")); 0633 collection2.setRemoteId(QLatin1StringView("collection2")); 0634 collection2.setParentCollection(mStore->topLevelCollection()); 0635 0636 job = mStore->fetchItems(collection2); 0637 0638 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0639 0640 QVERIFY(job->exec()); 0641 QCOMPARE(job->error(), 0); 0642 0643 items = job->items(); 0644 QCOMPARE((int)items.count(), 4); 0645 QCOMPARE(itemsFromSpy(spy), items); 0646 0647 QCOMPARE(items[0].remoteId(), QString::number(entryList2[0].messageOffset())); 0648 QCOMPARE(items[1].remoteId(), QString::number(entryList2[1].messageOffset())); 0649 QCOMPARE(items[2].remoteId(), QString::number(entryList2[2].messageOffset())); 0650 QCOMPARE(items[3].remoteId(), QString::number(entryList2[3].messageOffset())); 0651 0652 QCOMPARE(items[0].parentCollection(), collection2); 0653 QCOMPARE(items[1].parentCollection(), collection2); 0654 QCOMPARE(items[2].parentCollection(), collection2); 0655 QCOMPARE(items[3].parentCollection(), collection2); 0656 0657 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0658 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0659 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0660 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0661 0662 // see data/README 0663 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0664 QCOMPARE(items[1].flags(), 0665 QSet<QByteArray>() << "\\SEEN" 0666 << "$TODO"); 0667 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0668 QCOMPARE(items[3].flags(), 0669 QSet<QByteArray>() << "\\SEEN" 0670 << "\\FLAGGED"); 0671 0672 var = job->property("remoteIdToTagList"); 0673 QVERIFY(!var.isValid()); 0674 0675 // test listing empty mbox with index 0676 QFile file2(fileInfo2.absoluteFilePath()); 0677 QVERIFY(file2.open(QIODevice::WriteOnly | QIODevice::Truncate)); 0678 file2.close(); 0679 QCOMPARE((int)file2.size(), 0); 0680 0681 job = mStore->fetchItems(collection2); 0682 0683 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0684 0685 QVERIFY(job->exec()); 0686 QCOMPARE(job->error(), 0); 0687 0688 items = job->items(); 0689 QCOMPARE((int)items.count(), 0); 0690 QCOMPARE(spy->count(), 0); 0691 0692 var = job->property("remoteIdToTagList"); 0693 QVERIFY(!var.isValid()); 0694 0695 // test listing mbox with index which has tags 0696 Collection collection3; 0697 collection3.setName(QLatin1StringView("collection3")); 0698 collection3.setRemoteId(QLatin1StringView("collection3")); 0699 collection3.setParentCollection(mStore->topLevelCollection()); 0700 0701 job = mStore->fetchItems(collection3); 0702 0703 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0704 0705 QVERIFY(job->exec()); 0706 QCOMPARE(job->error(), 0); 0707 0708 items = job->items(); 0709 QCOMPARE((int)items.count(), 4); 0710 QCOMPARE(itemsFromSpy(spy), items); 0711 0712 QCOMPARE(items[0].remoteId(), QString::number(entryList3[0].messageOffset())); 0713 QCOMPARE(items[1].remoteId(), QString::number(entryList3[1].messageOffset())); 0714 QCOMPARE(items[2].remoteId(), QString::number(entryList3[2].messageOffset())); 0715 QCOMPARE(items[3].remoteId(), QString::number(entryList3[3].messageOffset())); 0716 0717 QCOMPARE(items[0].parentCollection(), collection3); 0718 QCOMPARE(items[1].parentCollection(), collection3); 0719 QCOMPARE(items[2].parentCollection(), collection3); 0720 QCOMPARE(items[3].parentCollection(), collection3); 0721 0722 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0723 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0724 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0725 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0726 0727 // see data/README 0728 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0729 QCOMPARE(items[1].flags(), 0730 QSet<QByteArray>() << "\\SEEN" 0731 << "$TODO"); 0732 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0733 QCOMPARE(items[3].flags(), 0734 QSet<QByteArray>() << "\\SEEN" 0735 << "\\FLAGGED"); 0736 0737 var = job->property("remoteIdToTagList"); 0738 QVERIFY(var.isValid()); 0739 0740 tagListHash = var.value<QHash<QString, QVariant>>(); 0741 QCOMPARE((int)tagListHash.count(), 3); 0742 QVERIFY(!tagListHash.value(items[0].remoteId()).toString().isEmpty()); 0743 QVERIFY(!tagListHash.contains(items[1].remoteId())); 0744 QVERIFY(!tagListHash.value(items[2].remoteId()).toString().isEmpty()); 0745 QVERIFY(!tagListHash.value(items[3].remoteId()).toString().isEmpty()); 0746 0747 // test listing mbox with index and unpurged messages (in mbox but not in index) 0748 Collection collection4; 0749 collection4.setName(QLatin1StringView("collection4")); 0750 collection4.setRemoteId(QLatin1StringView("collection4")); 0751 collection4.setParentCollection(mStore->topLevelCollection()); 0752 0753 job = mStore->fetchItems(collection4); 0754 0755 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0756 0757 QVERIFY(job->exec()); 0758 QCOMPARE(job->error(), 0); 0759 0760 items = job->items(); 0761 QCOMPARE((int)items.count(), 4); 0762 QCOMPARE(itemsFromSpy(spy), items); 0763 0764 QCOMPARE(items[0].remoteId(), QString::number(entryList4[0].messageOffset())); 0765 QCOMPARE(items[1].remoteId(), QString::number(entryList4[1].messageOffset())); 0766 QCOMPARE(items[2].remoteId(), QString::number(entryList4[2].messageOffset())); 0767 QCOMPARE(items[3].remoteId(), QString::number(entryList4[3].messageOffset())); 0768 0769 QCOMPARE(items[0].parentCollection(), collection4); 0770 QCOMPARE(items[1].parentCollection(), collection4); 0771 QCOMPARE(items[2].parentCollection(), collection4); 0772 QCOMPARE(items[3].parentCollection(), collection4); 0773 0774 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0775 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0776 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0777 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0778 0779 // see data/README 0780 QCOMPARE(items[0].flags(), QSet<QByteArray>() << "\\SEEN"); 0781 QCOMPARE(items[1].flags(), QSet<QByteArray>() << "\\DELETED"); 0782 QCOMPARE(items[2].flags(), QSet<QByteArray>() << "\\DELETED"); 0783 QCOMPARE(items[3].flags(), QSet<QByteArray>() << "\\SEEN"); 0784 0785 var = job->property("remoteIdToTagList"); 0786 QVERIFY(!var.isValid()); 0787 0788 // test listing mbox with index but newer modification date than index's one 0789 QFile file5(fileInfo5.absoluteFilePath()); 0790 QVERIFY(file5.open(QIODevice::ReadOnly)); 0791 const QByteArray data5 = file5.readAll(); 0792 file5.close(); 0793 0794 QTest::qSleep(1000); 0795 0796 QVERIFY(file5.open(QIODevice::WriteOnly)); 0797 file5.write(data5); 0798 file5.close(); 0799 0800 QCOMPARE(file5.size(), fileInfo5.size()); 0801 fileInfo5.refresh(); 0802 QFileInfo indexFileInfo5 = indexFile(fileInfo5); 0803 QVERIFY(fileInfo5.lastModified() > indexFileInfo5.lastModified()); 0804 0805 Collection collection5; 0806 collection5.setName(QLatin1StringView("collection5")); 0807 collection5.setRemoteId(QLatin1StringView("collection5")); 0808 collection5.setParentCollection(mStore->topLevelCollection()); 0809 0810 job = mStore->fetchItems(collection5); 0811 0812 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0813 0814 QVERIFY(job->exec()); 0815 QCOMPARE(job->error(), 0); 0816 0817 items = job->items(); 0818 QCOMPARE((int)items.count(), 4); 0819 QCOMPARE(itemsFromSpy(spy), items); 0820 0821 QCOMPARE(items[0].remoteId(), QString::number(entryList5[0].messageOffset())); 0822 QCOMPARE(items[1].remoteId(), QString::number(entryList5[1].messageOffset())); 0823 QCOMPARE(items[2].remoteId(), QString::number(entryList5[2].messageOffset())); 0824 QCOMPARE(items[3].remoteId(), QString::number(entryList5[3].messageOffset())); 0825 0826 QCOMPARE(items[0].parentCollection(), collection5); 0827 QCOMPARE(items[1].parentCollection(), collection5); 0828 QCOMPARE(items[2].parentCollection(), collection5); 0829 QCOMPARE(items[3].parentCollection(), collection5); 0830 0831 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0832 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0833 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0834 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0835 0836 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0837 QCOMPARE(items[1].flags(), QSet<QByteArray>()); 0838 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0839 QCOMPARE(items[3].flags(), QSet<QByteArray>()); 0840 0841 var = job->property("remoteIdToTagList"); 0842 QVERIFY(!var.isValid()); 0843 0844 // test that a new message in an mbox with index it not marked as deleted 0845 KMime::Message::Ptr msgPtr(new KMime::Message); 0846 msgPtr->subject()->from7BitString("Test 5"); 0847 msgPtr->to()->from7BitString("kevin.krammer@gmx.at"); 0848 msgPtr->assemble(); 0849 0850 Item item3_5; 0851 item3_5.setMimeType(KMime::Message::mimeType()); 0852 item3_5.setPayload<KMime::Message::Ptr>(msgPtr); 0853 0854 FileStore::ItemCreateJob *itemCreate = mStore->createItem(item3_5, collection3); 0855 QVERIFY(itemCreate->exec()); 0856 0857 item3_5 = itemCreate->item(); 0858 QVERIFY(!item3_5.remoteId().isEmpty()); 0859 0860 job = mStore->fetchItems(collection3); 0861 0862 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0863 0864 QVERIFY(job->exec()); 0865 QCOMPARE(job->error(), 0); 0866 0867 items = job->items(); 0868 QCOMPARE((int)items.count(), 5); 0869 QCOMPARE(itemsFromSpy(spy), items); 0870 0871 QCOMPARE(items[0].remoteId(), QString::number(entryList3[0].messageOffset())); 0872 QCOMPARE(items[1].remoteId(), QString::number(entryList3[1].messageOffset())); 0873 QCOMPARE(items[2].remoteId(), QString::number(entryList3[2].messageOffset())); 0874 QCOMPARE(items[3].remoteId(), QString::number(entryList3[3].messageOffset())); 0875 QCOMPARE(items[4].remoteId(), item3_5.remoteId()); 0876 0877 QCOMPARE(items[0].parentCollection(), collection3); 0878 QCOMPARE(items[1].parentCollection(), collection3); 0879 QCOMPARE(items[2].parentCollection(), collection3); 0880 QCOMPARE(items[3].parentCollection(), collection3); 0881 QCOMPARE(items[4].parentCollection(), collection3); 0882 0883 QVERIFY(!items[0].hasPayload<KMime::Message::Ptr>()); 0884 QVERIFY(!items[1].hasPayload<KMime::Message::Ptr>()); 0885 QVERIFY(!items[2].hasPayload<KMime::Message::Ptr>()); 0886 QVERIFY(!items[3].hasPayload<KMime::Message::Ptr>()); 0887 QVERIFY(!items[4].hasPayload<KMime::Message::Ptr>()); 0888 0889 // see data/README 0890 QCOMPARE(items[0].flags(), QSet<QByteArray>()); 0891 QCOMPARE(items[1].flags(), 0892 QSet<QByteArray>() << "\\SEEN" 0893 << "$TODO"); 0894 QCOMPARE(items[2].flags(), QSet<QByteArray>()); 0895 QCOMPARE(items[3].flags(), 0896 QSet<QByteArray>() << "\\SEEN" 0897 << "\\FLAGGED"); 0898 QCOMPARE(items[4].flags(), QSet<QByteArray>()); 0899 0900 var = job->property("remoteIdToTagList"); 0901 QVERIFY(var.isValid()); 0902 } 0903 0904 void ItemFetchTest::testSingleItemFetchMaildir() 0905 { 0906 QDir topDir(mDir->path()); 0907 0908 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("maildir"), topDir.path(), QLatin1StringView("collection1"))); 0909 0910 KPIM::Maildir topLevelMd(topDir.path(), true); 0911 0912 KPIM::Maildir md1 = topLevelMd.subFolder(QLatin1StringView("collection1")); 0913 QStringList entryList1 = md1.entryList(); 0914 QCOMPARE((int)entryList1.count(), 4); 0915 0916 KRandomSequence randomSequence; 0917 QStringList randomList1 = entryList1; 0918 randomSequence.randomize(randomList1); 0919 0920 mStore->setPath(topDir.path()); 0921 0922 // common variables 0923 FileStore::ItemFetchJob *job = 0; 0924 0925 QSignalSpy *spy = 0; 0926 Item::List items; 0927 0928 // test fetching from maildir, headers only 0929 Collection collection1; 0930 collection1.setName(QLatin1StringView("collection1")); 0931 collection1.setRemoteId(QLatin1StringView("collection1")); 0932 collection1.setParentCollection(mStore->topLevelCollection()); 0933 0934 for (const QString &entry : std::as_const(randomList1)) { 0935 Item item1; 0936 item1.setId(KRandom::random()); 0937 item1.setRemoteId(entry); 0938 item1.setParentCollection(collection1); 0939 0940 job = mStore->fetchItem(item1); 0941 job->fetchScope().fetchPayloadPart(MessagePart::Header); 0942 0943 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0944 0945 QVERIFY(job->exec()); 0946 QCOMPARE(job->error(), 0); 0947 0948 items = job->items(); 0949 QCOMPARE((int)items.count(), 1); 0950 QCOMPARE(itemsFromSpy(spy), items); 0951 0952 Item item = items.first(); 0953 QCOMPARE(item, item1); 0954 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 0955 0956 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 0957 QVERIFY(msgPtr != 0); 0958 0959 const QSet<QByteArray> parts = messageParts(msgPtr); 0960 QVERIFY(!parts.isEmpty()); 0961 QVERIFY(parts.contains(MessagePart::Header)); 0962 QVERIFY(!parts.contains(MessagePart::Body)); 0963 } 0964 0965 // test fetching from maildir, including body 0966 randomSequence.randomize(randomList1); 0967 for (const QString &entry : std::as_const(randomList1)) { 0968 Item item1; 0969 item1.setId(KRandom::random()); 0970 item1.setRemoteId(entry); 0971 item1.setParentCollection(collection1); 0972 0973 job = mStore->fetchItem(item1); 0974 job->fetchScope().fetchPayloadPart(MessagePart::Header); 0975 job->fetchScope().fetchPayloadPart(MessagePart::Body); 0976 0977 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 0978 0979 QVERIFY(job->exec()); 0980 QCOMPARE(job->error(), 0); 0981 0982 items = job->items(); 0983 QCOMPARE((int)items.count(), 1); 0984 QCOMPARE(itemsFromSpy(spy), items); 0985 0986 Item item = items.first(); 0987 QCOMPARE(item, item1); 0988 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 0989 0990 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 0991 QVERIFY(msgPtr != 0); 0992 0993 const QSet<QByteArray> parts = messageParts(msgPtr); 0994 QVERIFY(!parts.isEmpty()); 0995 QVERIFY(parts.contains(MessagePart::Header)); 0996 QVERIFY(parts.contains(MessagePart::Body)); 0997 } 0998 0999 // test fetching from maildir, just specifying full payload 1000 randomSequence.randomize(randomList1); 1001 for (const QString &entry : std::as_const(randomList1)) { 1002 Item item1; 1003 item1.setId(KRandom::random()); 1004 item1.setRemoteId(entry); 1005 item1.setParentCollection(collection1); 1006 1007 job = mStore->fetchItem(item1); 1008 job->fetchScope().fetchFullPayload(true); 1009 1010 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 1011 1012 QVERIFY(job->exec()); 1013 QCOMPARE(job->error(), 0); 1014 1015 items = job->items(); 1016 QCOMPARE((int)items.count(), 1); 1017 QCOMPARE(itemsFromSpy(spy), items); 1018 1019 Item item = items.first(); 1020 QCOMPARE(item, item1); 1021 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 1022 1023 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 1024 QVERIFY(msgPtr != 0); 1025 1026 const QSet<QByteArray> parts = messageParts(msgPtr); 1027 QVERIFY(!parts.isEmpty()); 1028 QVERIFY(parts.contains(MessagePart::Header)); 1029 QVERIFY(parts.contains(MessagePart::Body)); 1030 } 1031 } 1032 1033 void ItemFetchTest::testSingleItemFetchMBox() 1034 { 1035 QDir topDir(mDir->path()); 1036 1037 QVERIFY(TestDataUtil::installFolder(QLatin1StringView("mbox"), topDir.path(), QLatin1StringView("collection1"))); 1038 // one message has no body 1039 const QByteArray messageIdOfEmptyBodyMsg = "201007241551.37547.kevin.krammer@demo.kolab.org"; 1040 1041 QFileInfo fileInfo1(topDir.path(), QLatin1StringView("collection1")); 1042 MBox mbox1; 1043 QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); 1044 MBoxEntry::List entryList1 = mbox1.entries(); 1045 QCOMPARE((int)entryList1.count(), 4); 1046 1047 KRandomSequence randomSequence; 1048 MBoxEntry::List randomList1 = entryList1; 1049 randomSequence.randomize(randomList1); 1050 1051 mStore->setPath(topDir.path()); 1052 1053 // common variables 1054 FileStore::ItemFetchJob *job = 0; 1055 1056 QSignalSpy *spy = 0; 1057 Item::List items; 1058 1059 // test fetching from mbox, headers only 1060 Collection collection1; 1061 collection1.setName(QLatin1StringView("collection1")); 1062 collection1.setRemoteId(QLatin1StringView("collection1")); 1063 collection1.setParentCollection(mStore->topLevelCollection()); 1064 1065 for (const QString &entry : std::as_const(randomList1)) { 1066 Item item1; 1067 item1.setId(KRandom::random()); 1068 item1.setRemoteId(QString::number(entry.messageOffset())); 1069 item1.setParentCollection(collection1); 1070 1071 job = mStore->fetchItem(item1); 1072 job->fetchScope().fetchPayloadPart(MessagePart::Header); 1073 1074 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 1075 1076 QVERIFY(job->exec()); 1077 QCOMPARE(job->error(), 0); 1078 1079 items = job->items(); 1080 QCOMPARE((int)items.count(), 1); 1081 QCOMPARE(itemsFromSpy(spy), items); 1082 1083 Item item = items.first(); 1084 QCOMPARE(item, item1); 1085 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 1086 1087 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 1088 QVERIFY(msgPtr != 0); 1089 1090 const QSet<QByteArray> parts = messageParts(msgPtr); 1091 QVERIFY(!parts.isEmpty()); 1092 QVERIFY(parts.contains(MessagePart::Header)); 1093 QVERIFY(!parts.contains(MessagePart::Body)); 1094 } 1095 1096 // test fetching from mbox, including body 1097 randomSequence.randomize(randomList1); 1098 for (const QString &entry : std::as_const(randomList1)) { 1099 Item item1; 1100 item1.setId(KRandom::random()); 1101 item1.setRemoteId(QString::number(entry.messageOffset())); 1102 item1.setParentCollection(collection1); 1103 1104 job = mStore->fetchItem(item1); 1105 job->fetchScope().fetchPayloadPart(MessagePart::Header); 1106 job->fetchScope().fetchPayloadPart(MessagePart::Body); 1107 1108 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 1109 1110 QVERIFY(job->exec()); 1111 QCOMPARE(job->error(), 0); 1112 1113 items = job->items(); 1114 QCOMPARE((int)items.count(), 1); 1115 QCOMPARE(itemsFromSpy(spy), items); 1116 1117 Item item = items.first(); 1118 QCOMPARE(item, item1); 1119 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 1120 1121 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 1122 QVERIFY(msgPtr != 0); 1123 1124 const QSet<QByteArray> parts = messageParts(msgPtr); 1125 qCDebug(MIXEDMAILDIRRESOURCE_LOG) << msgPtr->messageID()->identifier(); 1126 QVERIFY(!parts.isEmpty()); 1127 QVERIFY(parts.contains(MessagePart::Header)); 1128 if (msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg) { 1129 QVERIFY(!parts.contains(MessagePart::Body)); 1130 } else { 1131 QVERIFY(parts.contains(MessagePart::Body)); 1132 } 1133 } 1134 1135 // test fetching from mbox, just specifying full payload 1136 randomSequence.randomize(randomList1); 1137 for (const QString &entry : std::as_const(randomList1)) { 1138 Item item1; 1139 item1.setId(KRandom::random()); 1140 item1.setRemoteId(QString::number(entry.messageOffset())); 1141 item1.setParentCollection(collection1); 1142 1143 job = mStore->fetchItem(item1); 1144 job->fetchScope().fetchFullPayload(true); 1145 1146 spy = new QSignalSpy(job, &FileStore::ItemFetchJob::itemsReceived); 1147 1148 QVERIFY(job->exec()); 1149 QCOMPARE(job->error(), 0); 1150 1151 items = job->items(); 1152 QCOMPARE((int)items.count(), 1); 1153 QCOMPARE(itemsFromSpy(spy), items); 1154 1155 Item item = items.first(); 1156 QCOMPARE(item, item1); 1157 QVERIFY(item.hasPayload<KMime::Message::Ptr>()); 1158 1159 KMime::Message::Ptr msgPtr = item.payload<KMime::Message::Ptr>(); 1160 QVERIFY(msgPtr != 0); 1161 1162 const QSet<QByteArray> parts = messageParts(msgPtr); 1163 QVERIFY(!parts.isEmpty()); 1164 QVERIFY(parts.contains(MessagePart::Header)); 1165 if (msgPtr->messageID()->identifier() == messageIdOfEmptyBodyMsg) { 1166 QVERIFY(!parts.contains(MessagePart::Body)); 1167 } else { 1168 QVERIFY(parts.contains(MessagePart::Body)); 1169 } 1170 } 1171 } 1172 1173 QTEST_MAIN(ItemFetchTest) 1174 1175 #include "itemfetchtest.moc"