File indexing completed on 2024-12-22 04:57:34

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 "filestore/collectiondeletejob.h"
0011 
0012 #include "libmaildir/maildir.h"
0013 
0014 #include <QTemporaryDir>
0015 
0016 #include <QDir>
0017 #include <QFileInfo>
0018 #include <QTest>
0019 
0020 using namespace Akonadi;
0021 
0022 class CollectionDeleteTest : public QObject
0023 {
0024     Q_OBJECT
0025 
0026 public:
0027     CollectionDeleteTest()
0028         : QObject()
0029         , mStore(nullptr)
0030         , mDir(nullptr)
0031     {
0032     }
0033 
0034     ~CollectionDeleteTest() override
0035     {
0036         delete mStore;
0037         delete mDir;
0038     }
0039 
0040 private:
0041     MixedMaildirStore *mStore = nullptr;
0042     QTemporaryDir *mDir = nullptr;
0043 
0044 private Q_SLOTS:
0045     void init();
0046     void cleanup();
0047     void testNonExisting();
0048     void testLeaves();
0049     void testSubTrees();
0050 };
0051 
0052 void CollectionDeleteTest::init()
0053 {
0054     mStore = new MixedMaildirStore;
0055 
0056     mDir = new QTemporaryDir;
0057     QVERIFY(mDir->isValid());
0058     QVERIFY(QDir(mDir->path()).exists());
0059 }
0060 
0061 void CollectionDeleteTest::cleanup()
0062 {
0063     delete mStore;
0064     mStore = nullptr;
0065     delete mDir;
0066     mDir = nullptr;
0067 }
0068 
0069 void CollectionDeleteTest::testNonExisting()
0070 {
0071     KPIM::Maildir topLevelMd(mDir->path(), true);
0072     QVERIFY(topLevelMd.isValid(false));
0073 
0074     KPIM::Maildir md1(topLevelMd.addSubFolder(QStringLiteral("collection1")), false);
0075     KPIM::Maildir md1_2(md1.addSubFolder(QStringLiteral("collection1_2")), false);
0076 
0077     KPIM::Maildir md2(topLevelMd.addSubFolder(QStringLiteral("collection2")), false);
0078 
0079     // simulate mbox
0080     QFileInfo fileInfo1(mDir->path(), QStringLiteral("collection3"));
0081     QFile file1(fileInfo1.absoluteFilePath());
0082     file1.open(QIODevice::WriteOnly);
0083     file1.close();
0084     QVERIFY(fileInfo1.exists());
0085 
0086     // simulate mbox with empty subtree
0087     QFileInfo fileInfo2(mDir->path(), QStringLiteral("collection4"));
0088     QFile file2(fileInfo2.absoluteFilePath());
0089     file2.open(QIODevice::WriteOnly);
0090     file2.close();
0091     QVERIFY(fileInfo2.exists());
0092 
0093     QFileInfo subDirInfo2(KPIM::Maildir::subDirPathForFolderPath(fileInfo2.absoluteFilePath()));
0094     QDir topDir(mDir->path());
0095     QVERIFY(topDir.mkpath(subDirInfo2.absoluteFilePath()));
0096 
0097     mStore->setPath(mDir->path());
0098 
0099     FileStore::CollectionDeleteJob *job = nullptr;
0100 
0101     // test fail of deleting first level collection
0102     Collection collection5;
0103     collection5.setName(QStringLiteral("collection5"));
0104     collection5.setRemoteId(QStringLiteral("collection5"));
0105     collection5.setParentCollection(mStore->topLevelCollection());
0106     job = mStore->deleteCollection(collection5);
0107     QVERIFY(job != nullptr);
0108 
0109     QVERIFY(!job->exec());
0110     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0111 
0112     QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2"));
0113     QVERIFY(fileInfo1.exists());
0114 
0115     // test fail of deleting second level collection in maildir leaf parent
0116     Collection collection2;
0117     collection2.setName(QStringLiteral("collection2"));
0118     collection2.setRemoteId(QStringLiteral("collection2"));
0119     collection2.setParentCollection(mStore->topLevelCollection());
0120 
0121     Collection collection2_1;
0122     collection2_1.setName(QStringLiteral("collection2_1"));
0123     collection2_1.setRemoteId(QStringLiteral("collection2_1"));
0124     collection2_1.setParentCollection(collection2);
0125     job = mStore->deleteCollection(collection2_1);
0126     QVERIFY(job != nullptr);
0127 
0128     QVERIFY(!job->exec());
0129     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0130 
0131     QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2"));
0132 
0133     // test fail of deleting second level collection in maildir parent with subtree
0134     Collection collection1;
0135     collection1.setName(QStringLiteral("collection1"));
0136     collection1.setRemoteId(QStringLiteral("collection1"));
0137     collection1.setParentCollection(mStore->topLevelCollection());
0138 
0139     Collection collection1_1;
0140     collection1_1.setName(QStringLiteral("collection1_1"));
0141     collection1_1.setRemoteId(QStringLiteral("collection1_1"));
0142     collection1_1.setParentCollection(collection1);
0143     job = mStore->deleteCollection(collection1_1);
0144     QVERIFY(job != nullptr);
0145 
0146     QVERIFY(!job->exec());
0147     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0148 
0149     QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2"));
0150     QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_2"));
0151 
0152     // test fail of deleting second level collection in mbox leaf parent
0153     Collection collection3;
0154     collection3.setName(QStringLiteral("collection3"));
0155     collection3.setRemoteId(QStringLiteral("collection3"));
0156     collection3.setParentCollection(mStore->topLevelCollection());
0157 
0158     Collection collection3_1;
0159     collection3_1.setName(QStringLiteral("collection3_1"));
0160     collection3_1.setRemoteId(QStringLiteral("collection3_1"));
0161     collection3_1.setParentCollection(collection3);
0162     job = mStore->deleteCollection(collection3_1);
0163     QVERIFY(job != nullptr);
0164 
0165     QVERIFY(!job->exec());
0166     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0167 
0168     QVERIFY(fileInfo1.exists());
0169 
0170     // test fail of deleting second level collection in mbox parent with subtree
0171     Collection collection4;
0172     collection4.setName(QStringLiteral("collection4"));
0173     collection4.setRemoteId(QStringLiteral("collection4"));
0174     collection4.setParentCollection(mStore->topLevelCollection());
0175 
0176     Collection collection4_1;
0177     collection4_1.setName(QStringLiteral("collection4_1"));
0178     collection4_1.setRemoteId(QStringLiteral("collection4_1"));
0179     collection4_1.setParentCollection(collection4);
0180     job = mStore->deleteCollection(collection4_1);
0181     QVERIFY(job != nullptr);
0182 
0183     QVERIFY(!job->exec());
0184     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0185 
0186     QVERIFY(fileInfo2.exists());
0187     QVERIFY(subDirInfo2.exists());
0188 
0189     // test fail of deleting second level collection with non existent parent
0190     Collection collection5_1;
0191     collection5_1.setName(QStringLiteral("collection5_1"));
0192     collection5_1.setRemoteId(QStringLiteral("collection5_1"));
0193     collection5_1.setParentCollection(collection5);
0194     job = mStore->deleteCollection(collection5_1);
0195     QVERIFY(job != nullptr);
0196 
0197     QVERIFY(!job->exec());
0198     QCOMPARE(job->error(), (int)FileStore::Job::InvalidJobContext);
0199 
0200     QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1") << QStringLiteral("collection2"));
0201     QVERIFY(fileInfo1.exists());
0202     QCOMPARE(md1.subFolderList(), QStringList() << QStringLiteral("collection1_2"));
0203 }
0204 
0205 void CollectionDeleteTest::testLeaves()
0206 {
0207     KPIM::Maildir topLevelMd(mDir->path(), true);
0208     QVERIFY(topLevelMd.isValid(false));
0209 
0210     QDir topDir(mDir->path());
0211 
0212     KPIM::Maildir md1(topLevelMd.addSubFolder(QStringLiteral("collection1")), false);
0213     KPIM::Maildir md1_2(md1.addSubFolder(QStringLiteral("collection1_2")), false);
0214 
0215     // simulate second level mbox in maildir parent
0216     QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), QStringLiteral("collection1_1"));
0217     QFile file1_1(fileInfo1_1.absoluteFilePath());
0218     file1_1.open(QIODevice::WriteOnly);
0219     file1_1.close();
0220     QVERIFY(fileInfo1_1.exists());
0221 
0222     KPIM::Maildir md2(topLevelMd.addSubFolder(QStringLiteral("collection2")), false);
0223 
0224     // simulate first level mbox
0225     QFileInfo fileInfo3(mDir->path(), QStringLiteral("collection3"));
0226     QFile file3(fileInfo3.absoluteFilePath());
0227     file3.open(QIODevice::WriteOnly);
0228     file3.close();
0229     QVERIFY(fileInfo3.exists());
0230 
0231     // simulate first level mbox with subtree
0232     QFileInfo fileInfo4(mDir->path(), QStringLiteral("collection4"));
0233     QFile file4(fileInfo4.absoluteFilePath());
0234     file4.open(QIODevice::WriteOnly);
0235     file4.close();
0236     QVERIFY(fileInfo4.exists());
0237 
0238     QFileInfo subDirInfo4(KPIM::Maildir::subDirPathForFolderPath(fileInfo4.absoluteFilePath()));
0239     QVERIFY(topDir.mkpath(subDirInfo4.absoluteFilePath()));
0240 
0241     KPIM::Maildir md4(subDirInfo4.absoluteFilePath(), true);
0242     KPIM::Maildir md4_1(md4.addSubFolder(QStringLiteral("collection4_1")), false);
0243 
0244     // simulate second level mbox in mbox parent
0245     QFileInfo fileInfo4_2(subDirInfo4.absoluteFilePath(), QStringLiteral("collection4_2"));
0246     QFile file4_2(fileInfo4_2.absoluteFilePath());
0247     file4_2.open(QIODevice::WriteOnly);
0248     file4_2.close();
0249     QVERIFY(fileInfo4_2.exists());
0250 
0251     mStore->setPath(mDir->path());
0252 
0253     FileStore::CollectionDeleteJob *job = nullptr;
0254 
0255     // test second level leaves in maildir parent
0256     Collection collection1;
0257     collection1.setName(QStringLiteral("collection1"));
0258     collection1.setRemoteId(QStringLiteral("collection1"));
0259     collection1.setParentCollection(mStore->topLevelCollection());
0260 
0261     Collection collection1_1;
0262     collection1_1.setName(QStringLiteral("collection1_1"));
0263     collection1_1.setRemoteId(QStringLiteral("collection1_1"));
0264     collection1_1.setParentCollection(collection1);
0265     job = mStore->deleteCollection(collection1_1);
0266     QVERIFY(job != nullptr);
0267 
0268     QVERIFY(job->exec());
0269     QCOMPARE(job->error(), 0);
0270 
0271     fileInfo1_1.refresh();
0272     QVERIFY(!fileInfo1_1.exists());
0273 
0274     Collection collection1_2;
0275     collection1_2.setName(QStringLiteral("collection1_2"));
0276     collection1_2.setRemoteId(QStringLiteral("collection1_2"));
0277     collection1_2.setParentCollection(collection1);
0278     job = mStore->deleteCollection(collection1_2);
0279     QVERIFY(job != nullptr);
0280 
0281     QVERIFY(job->exec());
0282     QCOMPARE(job->error(), 0);
0283 
0284     QVERIFY(!md1_2.isValid(false));
0285     QCOMPARE(md1.subFolderList(), QStringList());
0286 
0287     // test second level leaves in mbox parent
0288     Collection collection4;
0289     collection4.setName(QStringLiteral("collection4"));
0290     collection4.setRemoteId(QStringLiteral("collection4"));
0291     collection4.setParentCollection(mStore->topLevelCollection());
0292 
0293     Collection collection4_1;
0294     collection4_1.setName(QStringLiteral("collection4_1"));
0295     collection4_1.setRemoteId(QStringLiteral("collection4_1"));
0296     collection4_1.setParentCollection(collection4);
0297     job = mStore->deleteCollection(collection4_1);
0298     QVERIFY(job != nullptr);
0299 
0300     QVERIFY(job->exec());
0301     QCOMPARE(job->error(), 0);
0302 
0303     QVERIFY(!md4_1.isValid(false));
0304     QCOMPARE(md4.subFolderList(), QStringList());
0305 
0306     Collection collection4_2;
0307     collection4_2.setName(QStringLiteral("collection4_2"));
0308     collection4_2.setRemoteId(QStringLiteral("collection4_2"));
0309     collection4_2.setParentCollection(collection4);
0310     job = mStore->deleteCollection(collection4_2);
0311     QVERIFY(job != nullptr);
0312 
0313     QVERIFY(job->exec());
0314     QCOMPARE(job->error(), 0);
0315 
0316     fileInfo4_2.refresh();
0317     QVERIFY(!fileInfo4_2.exists());
0318 
0319     // test deleting of first level leaves
0320     Collection collection2;
0321     collection2.setName(QStringLiteral("collection2"));
0322     collection2.setRemoteId(QStringLiteral("collection2"));
0323     collection2.setParentCollection(mStore->topLevelCollection());
0324 
0325     job = mStore->deleteCollection(collection2);
0326     QVERIFY(job != nullptr);
0327 
0328     QVERIFY(job->exec());
0329     QCOMPARE(job->error(), 0);
0330 
0331     QVERIFY(!md2.isValid(false));
0332     QCOMPARE(topLevelMd.subFolderList(), QStringList() << QStringLiteral("collection1"));
0333 
0334     Collection collection3;
0335     collection3.setName(QStringLiteral("collection3"));
0336     collection3.setRemoteId(QStringLiteral("collection3"));
0337     collection3.setParentCollection(mStore->topLevelCollection());
0338 
0339     job = mStore->deleteCollection(collection3);
0340     QVERIFY(job != nullptr);
0341 
0342     QVERIFY(job->exec());
0343     QCOMPARE(job->error(), 0);
0344 
0345     fileInfo3.refresh();
0346     QVERIFY(!fileInfo3.exists());
0347 
0348     // test deleting of first level leaves with empty subtrees
0349     QFileInfo subDirInfo1(KPIM::Maildir::subDirPathForFolderPath(md1.path()));
0350     QVERIFY(subDirInfo1.exists());
0351 
0352     job = mStore->deleteCollection(collection1);
0353     QVERIFY(job != nullptr);
0354 
0355     QVERIFY(job->exec());
0356     QCOMPARE(job->error(), 0);
0357 
0358     QVERIFY(!md1.isValid(false));
0359     subDirInfo1.refresh();
0360     QVERIFY(!subDirInfo1.exists());
0361     QCOMPARE(topLevelMd.subFolderList(), QStringList());
0362 
0363     job = mStore->deleteCollection(collection4);
0364     QVERIFY(job != nullptr);
0365 
0366     QVERIFY(job->exec());
0367     QCOMPARE(job->error(), 0);
0368 
0369     fileInfo4.refresh();
0370     QVERIFY(!fileInfo4.exists());
0371     subDirInfo4.refresh();
0372     QVERIFY(!subDirInfo4.exists());
0373 }
0374 
0375 void CollectionDeleteTest::testSubTrees()
0376 {
0377     KPIM::Maildir topLevelMd(mDir->path(), true);
0378     QVERIFY(topLevelMd.isValid(false));
0379 
0380     QDir topDir(mDir->path());
0381 
0382     KPIM::Maildir md1(topLevelMd.addSubFolder(QStringLiteral("collection1")), false);
0383     KPIM::Maildir md1_2(md1.addSubFolder(QStringLiteral("collection1_2")), false);
0384 
0385     // simulate second level mbox in maildir parent
0386     QFileInfo fileInfo1_1(KPIM::Maildir::subDirPathForFolderPath(md1.path()), QStringLiteral("collection1_1"));
0387     QFile file1_1(fileInfo1_1.absoluteFilePath());
0388     file1_1.open(QIODevice::WriteOnly);
0389     file1_1.close();
0390     QVERIFY(fileInfo1_1.exists());
0391 
0392     // simulate first level mbox with subtree
0393     QFileInfo fileInfo2(mDir->path(), QStringLiteral("collection2"));
0394     QFile file2(fileInfo2.absoluteFilePath());
0395     file2.open(QIODevice::WriteOnly);
0396     file2.close();
0397     QVERIFY(fileInfo2.exists());
0398 
0399     QFileInfo subDirInfo2(KPIM::Maildir::subDirPathForFolderPath(fileInfo2.absoluteFilePath()));
0400     QVERIFY(topDir.mkpath(subDirInfo2.absoluteFilePath()));
0401 
0402     KPIM::Maildir md2(subDirInfo2.absoluteFilePath(), true);
0403     KPIM::Maildir md2_1(md2.addSubFolder(QStringLiteral("collection2_1")), false);
0404 
0405     // simulate second level mbox in mbox parent
0406     QFileInfo fileInfo2_2(subDirInfo2.absoluteFilePath(), QStringLiteral("collection2_2"));
0407     QFile file2_2(fileInfo2_2.absoluteFilePath());
0408     file2_2.open(QIODevice::WriteOnly);
0409     file2_2.close();
0410     QVERIFY(fileInfo2_2.exists());
0411 
0412     mStore->setPath(mDir->path());
0413 
0414     FileStore::CollectionDeleteJob *job = nullptr;
0415 
0416     // test deleting maildir subtree
0417     QFileInfo subDirInfo1(KPIM::Maildir::subDirPathForFolderPath(md1.path()));
0418     QVERIFY(subDirInfo1.exists());
0419 
0420     Collection collection1;
0421     collection1.setName(QStringLiteral("collection1"));
0422     collection1.setRemoteId(QStringLiteral("collection1"));
0423     collection1.setParentCollection(mStore->topLevelCollection());
0424 
0425     job = mStore->deleteCollection(collection1);
0426 
0427     QVERIFY(job->exec());
0428     QCOMPARE(job->error(), 0);
0429 
0430     QVERIFY(!md1.isValid(false));
0431     QVERIFY(!md1_2.isValid(false));
0432     fileInfo1_1.refresh();
0433     QVERIFY(!fileInfo1_1.exists());
0434 
0435     // test deleting mbox subtree
0436     Collection collection2;
0437     collection2.setName(QStringLiteral("collection2"));
0438     collection2.setRemoteId(QStringLiteral("collection2"));
0439     collection2.setParentCollection(mStore->topLevelCollection());
0440 
0441     job = mStore->deleteCollection(collection2);
0442 
0443     QVERIFY(job->exec());
0444     QCOMPARE(job->error(), 0);
0445 
0446     fileInfo2.refresh();
0447     QVERIFY(!fileInfo2.exists());
0448     QVERIFY(!md2_1.isValid(false));
0449     fileInfo2_2.refresh();
0450     QVERIFY(!fileInfo2_2.exists());
0451     QVERIFY(!subDirInfo2.exists());
0452 }
0453 
0454 QTEST_MAIN(CollectionDeleteTest)
0455 
0456 #include "collectiondeletetest.moc"