File indexing completed on 2024-12-22 04:57:38
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 "mixedmaildirstore.h" 0009 0010 #include "testdatautil.h" 0011 0012 #include "filestore/entitycompactchangeattribute.h" 0013 #include "filestore/itemfetchjob.h" 0014 #include "filestore/itemmovejob.h" 0015 #include "filestore/storecompactjob.h" 0016 0017 #include "libmaildir/maildir.h" 0018 0019 #include <KMbox/MBox> 0020 0021 #include <KRandom> 0022 0023 #include <QDir> 0024 #include <QFileInfo> 0025 #include <QRandomGenerator> 0026 #include <QTemporaryDir> 0027 #include <QTest> 0028 using namespace Akonadi; 0029 using namespace KMBox; 0030 0031 static bool fullEntryCompare(const MBoxEntry &a, const MBoxEntry &b) 0032 { 0033 return a.messageOffset() == b.messageOffset() && a.separatorSize() == b.separatorSize() && a.messageSize() == b.messageSize(); 0034 } 0035 0036 static quint64 changedOffset(const Item &item) 0037 { 0038 Q_ASSERT(item.hasAttribute<FileStore::EntityCompactChangeAttribute>()); 0039 0040 const QString remoteId = item.attribute<FileStore::EntityCompactChangeAttribute>()->remoteId(); 0041 Q_ASSERT(!remoteId.isEmpty()); 0042 0043 bool ok = false; 0044 const quint64 result = remoteId.toULongLong(&ok); 0045 Q_ASSERT(ok); 0046 0047 return result; 0048 } 0049 0050 class ItemMoveTest : public QObject 0051 { 0052 Q_OBJECT 0053 0054 public: 0055 ItemMoveTest() 0056 : QObject() 0057 , mStore(nullptr) 0058 , mDir(nullptr) 0059 { 0060 } 0061 0062 ~ItemMoveTest() override 0063 { 0064 delete mStore; 0065 delete mDir; 0066 } 0067 0068 private: 0069 MixedMaildirStore *mStore = nullptr; 0070 QTemporaryDir *mDir = nullptr; 0071 0072 private Q_SLOTS: 0073 void init(); 0074 void cleanup(); 0075 void testExpectedFail(); 0076 void testMaildirItem(); 0077 void testMBoxItem(); 0078 }; 0079 0080 void ItemMoveTest::init() 0081 { 0082 mStore = new MixedMaildirStore; 0083 0084 mDir = new QTemporaryDir; 0085 QVERIFY(mDir->isValid()); 0086 QVERIFY(QDir(mDir->path()).exists()); 0087 } 0088 0089 void ItemMoveTest::cleanup() 0090 { 0091 delete mStore; 0092 mStore = nullptr; 0093 delete mDir; 0094 mDir = nullptr; 0095 } 0096 0097 void ItemMoveTest::testExpectedFail() 0098 { 0099 QDir topDir(mDir->path()); 0100 0101 QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); 0102 QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); 0103 0104 KPIM::Maildir topLevelMd(topDir.path(), true); 0105 0106 KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); 0107 QStringList md1EntryList = md1.entryList(); 0108 QSet<QString> entrySet1(md1EntryList.cbegin(), md1EntryList.cend()); 0109 QCOMPARE((int)entrySet1.count(), 4); 0110 0111 QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); 0112 MBox mbox2; 0113 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0114 const MBoxEntry::List entryList2 = mbox2.entries(); 0115 QCOMPARE((int)entryList2.count(), 4); 0116 0117 QSet<qint64> entrySet2; 0118 for (const MBoxEntry &entry : entryList2) { 0119 entrySet2 << entry.messageOffset(); 0120 } 0121 0122 mStore->setPath(topDir.path()); 0123 0124 // common variables 0125 FileStore::ItemMoveJob *job = nullptr; 0126 0127 // test failure of moving from a non-existent collection 0128 Collection collection1; 0129 collection1.setName(QStringLiteral("collection1")); 0130 collection1.setRemoteId(QStringLiteral("collection1")); 0131 collection1.setParentCollection(mStore->topLevelCollection()); 0132 0133 Collection collection3; 0134 collection3.setName(QStringLiteral("collection3")); 0135 collection3.setRemoteId(QStringLiteral("collection3")); 0136 collection3.setParentCollection(mStore->topLevelCollection()); 0137 0138 Item item3; 0139 item3.setRemoteId(QStringLiteral("item3")); 0140 item3.setParentCollection(collection3); 0141 0142 job = mStore->moveItem(item3, collection1); 0143 QVERIFY(!job->exec()); 0144 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0145 0146 md1EntryList = md1.entryList(); 0147 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0148 0149 // test failure of moving from maildir to non-existent collection 0150 Item item1; 0151 item1.setId(QRandomGenerator::global()->generate()); 0152 item1.setRemoteId(*entrySet1.cbegin()); 0153 item1.setParentCollection(collection1); 0154 0155 job = mStore->moveItem(item1, collection3); 0156 QVERIFY(!job->exec()); 0157 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0158 0159 md1EntryList = md1.entryList(); 0160 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0161 0162 // test failure of moving from mbox to non-existent collection 0163 Collection collection2; 0164 collection2.setName(QStringLiteral("collection2")); 0165 collection2.setRemoteId(QStringLiteral("collection2")); 0166 collection2.setParentCollection(mStore->topLevelCollection()); 0167 0168 Item item2; 0169 item2.setId(QRandomGenerator::global()->generate()); 0170 item2.setRemoteId(QStringLiteral("0")); 0171 item2.setParentCollection(collection2); 0172 0173 job = mStore->moveItem(item1, collection3); 0174 QVERIFY(!job->exec()); 0175 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0176 0177 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0178 MBoxEntry::List tmpEntryList = mbox2.entries(); 0179 QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); 0180 0181 // test failure of moving from maildir to top level collection 0182 job = mStore->moveItem(item1, mStore->topLevelCollection()); 0183 QVERIFY(!job->exec()); 0184 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0185 0186 md1EntryList = md1.entryList(); 0187 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0188 0189 // test failure of moving from mbox to top level collection 0190 job = mStore->moveItem(item1, mStore->topLevelCollection()); 0191 QVERIFY(!job->exec()); 0192 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0193 0194 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0195 tmpEntryList = mbox2.entries(); 0196 QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); 0197 0198 // test failure of moving a non-existent maildir entry 0199 QString remoteId1; 0200 do { 0201 remoteId1 = KRandom::randomString(20); 0202 } while (entrySet1.contains(remoteId1)); 0203 0204 item1.setRemoteId(remoteId1); 0205 0206 job = mStore->moveItem(item1, collection2); 0207 QVERIFY(!job->exec()); 0208 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0209 0210 md1EntryList = md1.entryList(); 0211 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0212 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0213 tmpEntryList = mbox2.entries(); 0214 QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); 0215 0216 // test failure of moving a non-existent mbox entry 0217 quint64 remoteId2; 0218 do { 0219 remoteId2 = QRandomGenerator::global()->generate(); 0220 } while (entrySet2.contains(remoteId2)); 0221 0222 item2.setRemoteId(QString::number(remoteId2)); 0223 0224 job = mStore->moveItem(item2, collection1); 0225 QVERIFY(!job->exec()); 0226 QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext); 0227 0228 md1EntryList = md1.entryList(); 0229 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0230 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0231 tmpEntryList = mbox2.entries(); 0232 QVERIFY(std::equal(tmpEntryList.begin(), tmpEntryList.end(), entryList2.begin(), fullEntryCompare)); 0233 } 0234 0235 void ItemMoveTest::testMaildirItem() 0236 { 0237 QDir topDir(mDir->path()); 0238 0239 QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection1"))); 0240 QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection2"))); 0241 QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection5"))); 0242 0243 KPIM::Maildir topLevelMd(topDir.path(), true); 0244 0245 KPIM::Maildir md1 = topLevelMd.subFolder(QStringLiteral("collection1")); 0246 QStringList md1EntryList = md1.entryList(); 0247 QSet<QString> entrySet1(md1EntryList.cbegin(), md1EntryList.cend()); 0248 QCOMPARE((int)entrySet1.count(), 4); 0249 0250 QFileInfo fileInfo2(topDir.path(), QStringLiteral("collection2")); 0251 MBox mbox2; 0252 QVERIFY(mbox2.load(fileInfo2.absoluteFilePath())); 0253 MBoxEntry::List entryList2 = mbox2.entries(); 0254 QCOMPARE((int)entryList2.count(), 4); 0255 0256 KPIM::Maildir md3(topLevelMd.addSubFolder(QStringLiteral("collection3")), false); 0257 QVERIFY(md3.isValid()); 0258 QStringList md3EntryList = md3.entryList(); 0259 QSet<QString> entrySet3(md3EntryList.cbegin(), md3EntryList.cend()); 0260 QCOMPARE((int)entrySet3.count(), 0); 0261 0262 QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); 0263 QFile file4(fileInfo4.absoluteFilePath()); 0264 QVERIFY(file4.open(QIODevice::WriteOnly)); 0265 file4.close(); 0266 fileInfo4.refresh(); 0267 QVERIFY(fileInfo4.exists()); 0268 MBox mbox4; 0269 QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); 0270 MBoxEntry::List entryList4 = mbox4.entries(); 0271 QCOMPARE((int)entryList4.count(), 0); 0272 0273 KPIM::Maildir md5 = topLevelMd.subFolder(QStringLiteral("collection5")); 0274 QStringList md5EntryList = md5.entryList(); 0275 QSet<QString> entrySet5(md5EntryList.cbegin(), md5EntryList.cend()); 0276 QCOMPARE((int)entrySet5.count(), 4); 0277 0278 mStore->setPath(topDir.path()); 0279 0280 // common variables 0281 FileStore::ItemMoveJob *job = nullptr; 0282 0283 const QVariant colListVar = QVariant::fromValue<Collection::List>(Collection::List()); 0284 QVariant var; 0285 Collection::List collections; 0286 Item movedItem; 0287 MBoxEntry::List entryList; 0288 0289 // test moving to an empty maildir 0290 Collection collection1; 0291 collection1.setName(QStringLiteral("collection1")); 0292 collection1.setRemoteId(QStringLiteral("collection1")); 0293 collection1.setParentCollection(mStore->topLevelCollection()); 0294 0295 Collection collection3; 0296 collection3.setName(QStringLiteral("collection3")); 0297 collection3.setRemoteId(QStringLiteral("collection3")); 0298 collection3.setParentCollection(mStore->topLevelCollection()); 0299 0300 Item item1; 0301 item1.setId(QRandomGenerator::global()->generate()); 0302 item1.setRemoteId(*entrySet1.cbegin()); 0303 item1.setParentCollection(collection1); 0304 0305 job = mStore->moveItem(item1, collection3); 0306 0307 QVERIFY(job->exec()); 0308 QCOMPARE(job->error(), 0); 0309 0310 movedItem = job->item(); 0311 QCOMPARE(movedItem.id(), item1.id()); 0312 QCOMPARE(movedItem.parentCollection(), collection3); 0313 0314 entrySet3 << movedItem.remoteId(); 0315 md3EntryList = md3.entryList(); 0316 QCOMPARE(QSet<QString>(md3EntryList.cbegin(), md3EntryList.cend()), entrySet3); 0317 entrySet1.remove(item1.remoteId()); 0318 md1EntryList = md1.entryList(); 0319 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0320 0321 // check for index preservation 0322 var = job->property("onDiskIndexInvalidated"); 0323 QVERIFY(var.isValid()); 0324 QCOMPARE(var.userType(), colListVar.userType()); 0325 0326 collections = var.value<Collection::List>(); 0327 QCOMPARE((int)collections.count(), 1); 0328 QCOMPARE(collections.first(), collection1); 0329 0330 // test moving to a non empty maildir 0331 item1.setRemoteId(*entrySet1.cbegin()); 0332 0333 Collection collection5; 0334 collection5.setName(QStringLiteral("collection5")); 0335 collection5.setRemoteId(QStringLiteral("collection5")); 0336 collection5.setParentCollection(mStore->topLevelCollection()); 0337 0338 job = mStore->moveItem(item1, collection5); 0339 0340 QVERIFY(job->exec()); 0341 QCOMPARE(job->error(), 0); 0342 0343 movedItem = job->item(); 0344 QCOMPARE(movedItem.id(), item1.id()); 0345 QCOMPARE(movedItem.parentCollection(), collection5); 0346 0347 entrySet5 << movedItem.remoteId(); 0348 md5EntryList = md5.entryList(); 0349 QCOMPARE(QSet<QString>(md5EntryList.cbegin(), md5EntryList.cend()), entrySet5); 0350 entrySet1.remove(item1.remoteId()); 0351 md1EntryList = md1.entryList(); 0352 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0353 0354 // check for index preservation 0355 var = job->property("onDiskIndexInvalidated"); 0356 QVERIFY(var.isValid()); 0357 QCOMPARE(var.userType(), colListVar.userType()); 0358 0359 collections = var.value<Collection::List>(); 0360 QCOMPARE((int)collections.count(), 2); 0361 QCOMPARE(collections, Collection::List() << collection1 << collection5); 0362 0363 // test moving to an empty mbox 0364 Collection collection4; 0365 collection4.setName(QStringLiteral("collection4")); 0366 collection4.setRemoteId(QStringLiteral("collection4")); 0367 collection4.setParentCollection(mStore->topLevelCollection()); 0368 0369 item1.setRemoteId(*entrySet1.cbegin()); 0370 0371 job = mStore->moveItem(item1, collection4); 0372 0373 QVERIFY(job->exec()); 0374 QCOMPARE(job->error(), 0); 0375 0376 movedItem = job->item(); 0377 QCOMPARE(movedItem.id(), item1.id()); 0378 QCOMPARE(movedItem.parentCollection(), collection4); 0379 0380 QVERIFY(mbox4.load(mbox4.fileName())); 0381 entryList = mbox4.entries(); 0382 QCOMPARE((int)entryList.count(), 1); 0383 0384 QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); 0385 entrySet1.remove(item1.remoteId()); 0386 md1EntryList = md1.entryList(); 0387 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0388 0389 // check for index preservation 0390 var = job->property("onDiskIndexInvalidated"); 0391 QVERIFY(var.isValid()); 0392 QCOMPARE(var.userType(), colListVar.userType()); 0393 0394 collections = var.value<Collection::List>(); 0395 QCOMPARE((int)collections.count(), 1); 0396 QCOMPARE(collections.first(), collection1); 0397 0398 // test moving to a non empty mbox 0399 item1.setRemoteId(*entrySet1.cbegin()); 0400 0401 Collection collection2; 0402 collection2.setName(QStringLiteral("collection2")); 0403 collection2.setRemoteId(QStringLiteral("collection2")); 0404 collection2.setParentCollection(mStore->topLevelCollection()); 0405 0406 job = mStore->moveItem(item1, collection2); 0407 0408 QVERIFY(job->exec()); 0409 QCOMPARE(job->error(), 0); 0410 0411 movedItem = job->item(); 0412 QCOMPARE(movedItem.id(), item1.id()); 0413 QCOMPARE(movedItem.parentCollection(), collection2); 0414 0415 QVERIFY(mbox2.load(mbox2.fileName())); 0416 entryList = mbox2.entries(); 0417 QCOMPARE((int)entryList.count(), 5); 0418 0419 QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); 0420 entrySet1.remove(item1.remoteId()); 0421 md1EntryList = md1.entryList(); 0422 QCOMPARE(QSet<QString>(md1EntryList.cbegin(), md1EntryList.cend()), entrySet1); 0423 0424 // check for index preservation 0425 var = job->property("onDiskIndexInvalidated"); 0426 QVERIFY(var.isValid()); 0427 QCOMPARE(var.userType(), colListVar.userType()); 0428 0429 collections = var.value<Collection::List>(); 0430 QCOMPARE((int)collections.count(), 2); 0431 QCOMPARE(collections, Collection::List() << collection1 << collection2); 0432 } 0433 0434 void ItemMoveTest::testMBoxItem() 0435 { 0436 QDir topDir(mDir->path()); 0437 0438 QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection1"))); 0439 QVERIFY(TestDataUtil::installFolder(QStringLiteral("maildir"), topDir.path(), QStringLiteral("collection2"))); 0440 QVERIFY(TestDataUtil::installFolder(QStringLiteral("mbox"), topDir.path(), QStringLiteral("collection5"))); 0441 0442 QFileInfo fileInfo1(topDir.path(), QStringLiteral("collection1")); 0443 MBox mbox1; 0444 QVERIFY(mbox1.load(fileInfo1.absoluteFilePath())); 0445 MBoxEntry::List entryList1 = mbox1.entries(); 0446 QCOMPARE((int)entryList1.count(), 4); 0447 0448 KPIM::Maildir topLevelMd(topDir.path(), true); 0449 0450 KPIM::Maildir md2 = topLevelMd.subFolder(QStringLiteral("collection2")); 0451 QStringList md2EntryList = md2.entryList(); 0452 QSet<QString> entrySet2(md2EntryList.cbegin(), md2EntryList.cend()); 0453 QCOMPARE((int)entrySet2.count(), 4); 0454 0455 KPIM::Maildir md3(topLevelMd.addSubFolder(QStringLiteral("collection3")), false); 0456 QVERIFY(md3.isValid()); 0457 QStringList md3EntryList = md3.entryList(); 0458 QSet<QString> entrySet3(md3EntryList.cbegin(), md3EntryList.cend()); 0459 QCOMPARE((int)entrySet3.count(), 0); 0460 0461 QFileInfo fileInfo4(topDir.path(), QStringLiteral("collection4")); 0462 QFile file4(fileInfo4.absoluteFilePath()); 0463 QVERIFY(file4.open(QIODevice::WriteOnly)); 0464 file4.close(); 0465 fileInfo4.refresh(); 0466 QVERIFY(fileInfo4.exists()); 0467 MBox mbox4; 0468 QVERIFY(mbox4.load(fileInfo4.absoluteFilePath())); 0469 MBoxEntry::List entryList4 = mbox4.entries(); 0470 QCOMPARE((int)entryList4.count(), 0); 0471 0472 QFileInfo fileInfo5(topDir.path(), QStringLiteral("collection5")); 0473 MBox mbox5; 0474 QVERIFY(mbox5.load(fileInfo5.absoluteFilePath())); 0475 MBoxEntry::List entryList5 = mbox5.entries(); 0476 QCOMPARE((int)entryList5.count(), 4); 0477 0478 mStore->setPath(topDir.path()); 0479 0480 // common variables 0481 FileStore::ItemMoveJob *job = nullptr; 0482 FileStore::StoreCompactJob *compactStore = nullptr; 0483 0484 const QVariant colListVar = QVariant::fromValue<Collection::List>(Collection::List()); 0485 QVariant var; 0486 Collection::List collections; 0487 Item movedItem; 0488 MBoxEntry::List entryList; 0489 Item::List items; 0490 0491 // test moving to an empty maildir 0492 Collection collection1; 0493 collection1.setName(QStringLiteral("collection1")); 0494 collection1.setRemoteId(QStringLiteral("collection1")); 0495 collection1.setParentCollection(mStore->topLevelCollection()); 0496 0497 Collection collection3; 0498 collection3.setName(QStringLiteral("collection3")); 0499 collection3.setRemoteId(QStringLiteral("collection3")); 0500 collection3.setParentCollection(mStore->topLevelCollection()); 0501 0502 Item item1; 0503 item1.setId(QRandomGenerator::global()->generate()); 0504 item1.setRemoteId(QString::number(entryList1.first().messageOffset())); 0505 item1.setParentCollection(collection1); 0506 0507 job = mStore->moveItem(item1, collection3); 0508 0509 QVERIFY(job->exec()); 0510 QCOMPARE(job->error(), 0); 0511 0512 movedItem = job->item(); 0513 QCOMPARE(movedItem.id(), item1.id()); 0514 QCOMPARE(movedItem.parentCollection(), collection3); 0515 0516 var = job->property("compactStore"); 0517 QVERIFY(var.isValid()); 0518 QCOMPARE(var.userType(), QMetaType::Bool); 0519 QCOMPARE(var.toBool(), true); 0520 0521 compactStore = mStore->compactStore(); 0522 QVERIFY(compactStore->exec()); 0523 0524 items = compactStore->changedItems(); 0525 QCOMPARE((int)items.count(), 3); 0526 0527 entrySet3 << movedItem.remoteId(); 0528 md3EntryList = md3.entryList(); 0529 QCOMPARE(QSet<QString>(md3EntryList.cbegin(), md3EntryList.cend()), entrySet3); 0530 0531 entryList1.removeAt(0); 0532 entryList1[0] = MBoxEntry(changedOffset(items[0])); 0533 entryList1[1] = MBoxEntry(changedOffset(items[1])); 0534 entryList1[2] = MBoxEntry(changedOffset(items[2])); 0535 QVERIFY(mbox1.load(mbox1.fileName())); 0536 QCOMPARE(mbox1.entries(), entryList1); 0537 0538 // test moving to a non empty mbox 0539 Collection collection5; 0540 collection5.setName(QStringLiteral("collection5")); 0541 collection5.setRemoteId(QStringLiteral("collection5")); 0542 collection5.setParentCollection(mStore->topLevelCollection()); 0543 0544 job = mStore->moveItem(item1, collection5); 0545 0546 QVERIFY(job->exec()); 0547 QCOMPARE(job->error(), 0); 0548 0549 movedItem = job->item(); 0550 QCOMPARE(movedItem.id(), item1.id()); 0551 QCOMPARE(movedItem.parentCollection(), collection5); 0552 0553 var = job->property("compactStore"); 0554 QVERIFY(var.isValid()); 0555 QCOMPARE(var.userType(), QMetaType::Bool); 0556 QCOMPARE(var.toBool(), true); 0557 0558 // check for index preservation 0559 var = job->property("onDiskIndexInvalidated"); 0560 QVERIFY(var.isValid()); 0561 QCOMPARE(var.userType(), colListVar.userType()); 0562 0563 collections = var.value<Collection::List>(); 0564 QCOMPARE((int)collections.count(), 2); 0565 QCOMPARE(collections, Collection::List() << collection1 << collection5); 0566 0567 compactStore = mStore->compactStore(); 0568 QVERIFY(compactStore->exec()); 0569 0570 items = compactStore->changedItems(); 0571 QCOMPARE((int)items.count(), 2); 0572 0573 QVERIFY(mbox5.load(mbox5.fileName())); 0574 QCOMPARE(mbox5.entries().count(), entryList5.count() + 1); 0575 QCOMPARE(mbox5.entries().last().messageOffset(), movedItem.remoteId().toULongLong()); 0576 0577 entryList1.removeAt(0); 0578 entryList1[0] = MBoxEntry(changedOffset(items[0])); 0579 entryList1[1] = MBoxEntry(changedOffset(items[1])); 0580 QVERIFY(mbox1.load(mbox1.fileName())); 0581 QCOMPARE(mbox1.entries(), entryList1); 0582 0583 // test moving to an empty mbox 0584 Collection collection4; 0585 collection4.setName(QStringLiteral("collection4")); 0586 collection4.setRemoteId(QStringLiteral("collection4")); 0587 collection4.setParentCollection(mStore->topLevelCollection()); 0588 0589 job = mStore->moveItem(item1, collection4); 0590 0591 QVERIFY(job->exec()); 0592 QCOMPARE(job->error(), 0); 0593 0594 movedItem = job->item(); 0595 QCOMPARE(movedItem.id(), item1.id()); 0596 QCOMPARE(movedItem.parentCollection(), collection4); 0597 0598 QVERIFY(mbox4.load(mbox4.fileName())); 0599 entryList = mbox4.entries(); 0600 QCOMPARE((int)entryList.count(), 1); 0601 0602 QCOMPARE(entryList.last().messageOffset(), movedItem.remoteId().toULongLong()); 0603 0604 var = job->property("compactStore"); 0605 QVERIFY(var.isValid()); 0606 QCOMPARE(var.userType(), QMetaType::Bool); 0607 QCOMPARE(var.toBool(), true); 0608 0609 // check for index preservation 0610 var = job->property("onDiskIndexInvalidated"); 0611 QVERIFY(var.isValid()); 0612 QCOMPARE(var.userType(), colListVar.userType()); 0613 0614 collections = var.value<Collection::List>(); 0615 QCOMPARE((int)collections.count(), 1); 0616 QCOMPARE(collections.first(), collection1); 0617 0618 compactStore = mStore->compactStore(); 0619 QVERIFY(compactStore->exec()); 0620 0621 items = compactStore->changedItems(); 0622 QCOMPARE((int)items.count(), 1); 0623 0624 QCOMPARE(mbox4.entries().count(), entryList4.count() + 1); 0625 QCOMPARE(mbox4.entries().last().messageOffset(), movedItem.remoteId().toULongLong()); 0626 0627 entryList1.removeAt(0); 0628 entryList1[0] = MBoxEntry(changedOffset(items[0])); 0629 QVERIFY(mbox1.load(mbox1.fileName())); 0630 QCOMPARE(mbox1.entries(), entryList1); 0631 0632 // test moving to a non empty maildir 0633 Collection collection2; 0634 collection2.setName(QStringLiteral("collection2")); 0635 collection2.setRemoteId(QStringLiteral("collection2")); 0636 collection2.setParentCollection(mStore->topLevelCollection()); 0637 0638 job = mStore->moveItem(item1, collection2); 0639 0640 QVERIFY(job->exec()); 0641 QCOMPARE(job->error(), 0); 0642 0643 movedItem = job->item(); 0644 QCOMPARE(movedItem.id(), item1.id()); 0645 QCOMPARE(movedItem.parentCollection(), collection2); 0646 0647 md2EntryList = md2.entryList(); 0648 QSet<QString> entrySet(md2EntryList.cbegin(), md2EntryList.cend()); 0649 QCOMPARE((int)entrySet.count(), 5); 0650 0651 QVERIFY(entrySet.contains(movedItem.remoteId())); 0652 0653 var = job->property("compactStore"); 0654 QVERIFY(var.isValid()); 0655 QCOMPARE(var.userType(), QMetaType::Bool); 0656 QCOMPARE(var.toBool(), true); 0657 0658 // check for index preservation 0659 var = job->property("onDiskIndexInvalidated"); 0660 QVERIFY(var.isValid()); 0661 QCOMPARE(var.userType(), colListVar.userType()); 0662 0663 collections = var.value<Collection::List>(); 0664 QCOMPARE((int)collections.count(), 2); 0665 QCOMPARE(collections.first(), collection1); 0666 0667 compactStore = mStore->compactStore(); 0668 QVERIFY(compactStore->exec()); 0669 0670 items = compactStore->changedItems(); 0671 QCOMPARE((int)items.count(), 0); 0672 0673 entryList1.removeAt(0); 0674 QVERIFY(mbox1.load(mbox1.fileName())); 0675 const MBoxEntry::List newEntryList = mbox1.entries(); 0676 QVERIFY(std::equal(newEntryList.begin(), newEntryList.end(), entryList1.begin(), fullEntryCompare)); 0677 } 0678 0679 QTEST_MAIN(ItemMoveTest) 0680 0681 #include "itemmovetest.moc"