File indexing completed on 2024-05-12 05:11:09

0001 /*
0002     SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "localfolderstest.h"
0008 
0009 #include "collectionpathresolver.h"
0010 #include "specialmailcollectionssettings.h"
0011 
0012 #include <QDBusConnection>
0013 #include <QDBusConnectionInterface>
0014 #include <QFile>
0015 #include <QSignalSpy>
0016 
0017 #include "../src/specialmailcollectionstesting_p.h"
0018 #include "specialcollectionattribute.h"
0019 #include "specialcollections.h"
0020 #include "specialmailcollections.h"
0021 #include <Akonadi/AgentInstance>
0022 #include <Akonadi/AgentManager>
0023 #include <Akonadi/CollectionCreateJob>
0024 #include <Akonadi/CollectionDeleteJob>
0025 #include <Akonadi/CollectionFetchJob>
0026 #include <Akonadi/CollectionModifyJob>
0027 #include <Akonadi/ServerManager>
0028 #include <KLocalizedString>
0029 #include <QStandardPaths>
0030 #include <akonadi/qtest_akonadi.h>
0031 #include <control.h>
0032 
0033 using namespace Akonadi;
0034 
0035 typedef SpecialMailCollectionsSettings Settings;
0036 
0037 static Collection res1;
0038 
0039 void LocalFoldersTest::initTestCase()
0040 {
0041     qRegisterMetaType<Akonadi::AgentInstance>("Akonadi::AgentInstance");
0042 
0043     mDisplayNameMap.insert("local-mail", i18nc("local mail folder", "Local Folders"));
0044     mDisplayNameMap.insert("inbox", i18nc("local mail folder", "inbox"));
0045     mDisplayNameMap.insert("outbox", i18nc("local mail folder", "outbox"));
0046     mDisplayNameMap.insert("sent-mail", i18nc("local mail folder", "sent-mail"));
0047     mDisplayNameMap.insert("trash", i18nc("local mail folder", "trash"));
0048     mDisplayNameMap.insert("drafts", i18nc("local mail folder", "drafts"));
0049     mDisplayNameMap.insert("templates", i18nc("local mail folder", "templates"));
0050 
0051     mIconNameMap.insert("local-mail", QLatin1StringView("folder"));
0052     mIconNameMap.insert("inbox", QLatin1StringView("mail-folder-inbox"));
0053     mIconNameMap.insert("outbox", QLatin1StringView("mail-folder-outbox"));
0054     mIconNameMap.insert("sent-mail", QLatin1StringView("mail-folder-sent"));
0055     mIconNameMap.insert("trash", QLatin1StringView("user-trash"));
0056     mIconNameMap.insert("drafts", QLatin1StringView("document-properties"));
0057     mIconNameMap.insert("templates", QLatin1StringView("document-new"));
0058 
0059     QVERIFY(Control::start());
0060     QTest::qWait(1000);
0061 
0062     CollectionPathResolver *resolver = new CollectionPathResolver(QStringLiteral("res1"), this);
0063     QVERIFY(resolver->exec());
0064     res1 = Collection(resolver->collection());
0065 
0066     CollectionFetchJob *fjob = new CollectionFetchJob(res1, CollectionFetchJob::Base, this);
0067     AKVERIFYEXEC(fjob);
0068     Q_ASSERT(fjob->collections().count() == 1);
0069     res1 = fjob->collections().first();
0070     QVERIFY(!res1.resource().isEmpty());
0071 }
0072 
0073 void LocalFoldersTest::testLock()
0074 {
0075     QString dbusName = QString::fromLatin1("org.kde.pim.SpecialCollections");
0076     if (ServerManager::hasInstanceIdentifier()) {
0077         dbusName += Akonadi::ServerManager::instanceIdentifier();
0078     }
0079 
0080     // Initially not locked.
0081     QVERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(dbusName));
0082 
0083     // Get the lock.
0084     {
0085         GetLockJob *ljob = new GetLockJob(this);
0086         AKVERIFYEXEC(ljob);
0087         QVERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(dbusName));
0088     }
0089 
0090     // Getting the lock again should fail.
0091     {
0092         GetLockJob *ljob = new GetLockJob(this);
0093         QVERIFY(!ljob->exec());
0094     }
0095 
0096     // Release the lock.
0097     QVERIFY(QDBusConnection::sessionBus().interface()->isServiceRegistered(dbusName));
0098     releaseLock();
0099     QVERIFY(!QDBusConnection::sessionBus().interface()->isServiceRegistered(dbusName));
0100 }
0101 
0102 void LocalFoldersTest::testInitialState()
0103 {
0104     SpecialMailCollections *smc = SpecialMailCollections::self();
0105     SpecialCollections *sc = smc;
0106     SpecialMailCollectionsTesting *smct = SpecialMailCollectionsTesting::_t_self();
0107     Q_ASSERT(smc);
0108     Q_ASSERT(smct);
0109     Q_UNUSED(smct)
0110 
0111     // No one has created the default resource.
0112     QVERIFY(sc->d->defaultResource().identifier().isEmpty());
0113 
0114     // LF does not have a default Outbox folder (or any other).
0115     QCOMPARE(smc->hasDefaultCollection(SpecialMailCollections::Outbox), false);
0116     QVERIFY(!smc->defaultCollection(SpecialMailCollections::Outbox).isValid());
0117 
0118     // LF treats unknown resources correctly.
0119     const QString resourceId = QString::fromLatin1("this_resource_does_not_exist");
0120     QCOMPARE(smc->hasCollection(SpecialMailCollections::Outbox, AgentManager::self()->instance(resourceId)), false);
0121     QVERIFY(!smc->collection(SpecialMailCollections::Outbox, AgentManager::self()->instance(resourceId)).isValid());
0122 }
0123 
0124 void LocalFoldersTest::testRegistrationErrors()
0125 {
0126     SpecialMailCollections *smc = SpecialMailCollections::self();
0127 
0128     // A valid collection that can be registered.
0129     Collection outbox;
0130     outbox.setName(QLatin1StringView("my_outbox"));
0131     outbox.setParentCollection(res1);
0132     outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0133     outbox.setResource(res1.resource());
0134 
0135     // Needs to be valid.
0136     {
0137         Collection col(outbox);
0138         col.setId(-1);
0139         QVERIFY(!smc->registerCollection(SpecialMailCollections::Outbox, col));
0140     }
0141 
0142     // Needs to have a resourceId.
0143     {
0144         Collection col(outbox);
0145         col.setResource(QString());
0146         QVERIFY(!smc->registerCollection(SpecialMailCollections::Outbox, col));
0147     }
0148 
0149     // Needs to have a LocalFolderAttribute.
0150     {
0151         Collection col(outbox);
0152         col.removeAttribute<SpecialCollectionAttribute>();
0153         QVERIFY(!smc->registerCollection(SpecialMailCollections::Outbox, col));
0154     }
0155 }
0156 
0157 void LocalFoldersTest::testDefaultFolderRegistration()
0158 {
0159     SpecialMailCollections *smc = SpecialMailCollections::self();
0160     SpecialCollections *sc = smc;
0161     SpecialMailCollectionsTesting *smct = SpecialMailCollectionsTesting::_t_self();
0162     Q_ASSERT(smc);
0163     Q_ASSERT(smct);
0164     QSignalSpy spy(smc, &SpecialMailCollections::collectionsChanged);
0165     QSignalSpy defSpy(smc, &SpecialMailCollections::defaultCollectionsChanged);
0166     QVERIFY(spy.isValid());
0167     QVERIFY(defSpy.isValid());
0168 
0169     // No one has created the default resource.
0170     QVERIFY(sc->d->defaultResource().identifier().isEmpty());
0171 
0172     // Set the default resource. LF should still have no folders.
0173     smct->_t_setDefaultResourceId(res1.resource());
0174     QCOMPARE(sc->d->defaultResource().identifier(), res1.resource());
0175     QCOMPARE(smct->_t_knownResourceCount(), 0);
0176     QCOMPARE(smct->_t_knownFolderCount(), 0);
0177 
0178     // Manually create an Outbox collection.
0179     Collection outbox;
0180     outbox.setName(QLatin1StringView("my_outbox"));
0181     outbox.setParentCollection(res1);
0182     outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0183     CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0184     AKVERIFYEXEC(cjob);
0185     outbox = cjob->collection();
0186 
0187     // LF should still have no folders, since the Outbox wasn't registered.
0188     QCOMPARE(smct->_t_knownResourceCount(), 0);
0189     QCOMPARE(smct->_t_knownFolderCount(), 0);
0190     QCOMPARE(spy.count(), 0);
0191     QCOMPARE(defSpy.count(), 0);
0192 
0193     // Register the collection. LF should now know it.
0194     bool ok = smc->registerCollection(SpecialMailCollections::Outbox, outbox);
0195     QVERIFY(ok);
0196     QVERIFY(smc->hasDefaultCollection(SpecialMailCollections::Outbox));
0197     QCOMPARE(smc->defaultCollection(SpecialMailCollections::Outbox), outbox);
0198     QCOMPARE(smct->_t_knownResourceCount(), 1);
0199     QCOMPARE(smct->_t_knownFolderCount(), 1);
0200     QCOMPARE(spy.count(), 1);
0201     QCOMPARE(defSpy.count(), 1);
0202 
0203     // Forget all folders in the default resource.
0204     smct->_t_forgetFoldersForResource(sc->d->defaultResource().identifier());
0205     QCOMPARE(smc->hasDefaultCollection(SpecialMailCollections::Outbox), false);
0206     QCOMPARE(smct->_t_knownResourceCount(), 0);
0207     QCOMPARE(smct->_t_knownFolderCount(), 0);
0208     QCOMPARE(spy.count(), 2);
0209     QCOMPARE(defSpy.count(), 2);
0210 
0211     // Delete the collection.
0212     CollectionDeleteJob *djob = new CollectionDeleteJob(outbox, this);
0213     AKVERIFYEXEC(djob);
0214 }
0215 
0216 void LocalFoldersTest::testCustomFolderRegistration()
0217 {
0218     SpecialMailCollections *smc = SpecialMailCollections::self();
0219     SpecialMailCollectionsTesting *smct = SpecialMailCollectionsTesting::_t_self();
0220     Q_ASSERT(smc);
0221     Q_ASSERT(smct);
0222     QSignalSpy spy(smc, &SpecialMailCollections::collectionsChanged);
0223     QSignalSpy defSpy(smc, &SpecialMailCollections::defaultCollectionsChanged);
0224     QVERIFY(spy.isValid());
0225     QVERIFY(defSpy.isValid());
0226 
0227     // Set a fake default resource, so that res1.resource() isn't seen as the default one.
0228     // LF should have no folders.
0229     smct->_t_setDefaultResourceId("dummy");
0230     QCOMPARE(smct->_t_knownResourceCount(), 0);
0231     QCOMPARE(smct->_t_knownFolderCount(), 0);
0232 
0233     // Manually create an Outbox collection.
0234     Collection outbox;
0235     outbox.setName(QLatin1StringView("my_outbox"));
0236     outbox.setParentCollection(res1);
0237     outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0238     CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0239     AKVERIFYEXEC(cjob);
0240     outbox = cjob->collection();
0241 
0242     // LF should still have no folders, since the Outbox wasn't registered.
0243     QCOMPARE(smct->_t_knownResourceCount(), 0);
0244     QCOMPARE(smct->_t_knownFolderCount(), 0);
0245     QCOMPARE(spy.count(), 0);
0246     QCOMPARE(defSpy.count(), 0);
0247 
0248     // Register the collection. LF should now know it.
0249     bool ok = smc->registerCollection(SpecialMailCollections::Outbox, outbox);
0250     QVERIFY(ok);
0251     QVERIFY(!smc->hasDefaultCollection(SpecialMailCollections::Outbox));
0252     QVERIFY(smc->hasCollection(SpecialMailCollections::Outbox, AgentManager::self()->instance(outbox.resource())));
0253     QCOMPARE(smc->collection(SpecialMailCollections::Outbox, AgentManager::self()->instance(outbox.resource())), outbox);
0254     QCOMPARE(smct->_t_knownResourceCount(), 1);
0255     QCOMPARE(smct->_t_knownFolderCount(), 1);
0256     QCOMPARE(spy.count(), 1);
0257     QCOMPARE(defSpy.count(), 0);
0258 
0259     // Forget all folders in this resource.
0260     smct->_t_forgetFoldersForResource(outbox.resource());
0261     QCOMPARE(smc->hasDefaultCollection(SpecialMailCollections::Outbox), false);
0262     QCOMPARE(smc->hasCollection(SpecialMailCollections::Outbox, AgentManager::self()->instance(outbox.resource())), false);
0263     QCOMPARE(smct->_t_knownResourceCount(), 0);
0264     QCOMPARE(smct->_t_knownFolderCount(), 0);
0265     QCOMPARE(spy.count(), 2);
0266     QCOMPARE(defSpy.count(), 0);
0267 
0268     // Delete the collection.
0269     CollectionDeleteJob *djob = new CollectionDeleteJob(outbox, this);
0270     AKVERIFYEXEC(djob);
0271 }
0272 
0273 void LocalFoldersTest::testCollectionDelete()
0274 {
0275     SpecialMailCollections *smc = SpecialMailCollections::self();
0276     SpecialCollections *sc = smc;
0277     SpecialMailCollectionsTesting *smct = SpecialMailCollectionsTesting::_t_self();
0278     Q_ASSERT(smc);
0279     Q_ASSERT(smct);
0280     QSignalSpy spy(smc, &SpecialMailCollections::collectionsChanged);
0281     QSignalSpy defSpy(smc, &SpecialMailCollections::defaultCollectionsChanged);
0282     QVERIFY(spy.isValid());
0283     QVERIFY(defSpy.isValid());
0284 
0285     // Set the default resource. LF should have no folders.
0286     smct->_t_setDefaultResourceId(res1.resource());
0287     QCOMPARE(sc->d->defaultResource().identifier(), res1.resource());
0288     QCOMPARE(smct->_t_knownResourceCount(), 0);
0289     QCOMPARE(smct->_t_knownFolderCount(), 0);
0290 
0291     // Manually create an Outbox collection.
0292     Collection outbox;
0293     outbox.setName(QLatin1StringView("my_outbox"));
0294     outbox.setParentCollection(res1);
0295     outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0296     CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0297     AKVERIFYEXEC(cjob);
0298     outbox = cjob->collection();
0299 
0300     // LF should still have no folders, since the Outbox wasn't registered.
0301     QCOMPARE(smct->_t_knownResourceCount(), 0);
0302     QCOMPARE(smct->_t_knownFolderCount(), 0);
0303     QCOMPARE(spy.count(), 0);
0304     QCOMPARE(defSpy.count(), 0);
0305 
0306     // Register the collection. LF should now know it.
0307     bool ok = smc->registerCollection(SpecialMailCollections::Outbox, outbox);
0308     QVERIFY(ok);
0309     QVERIFY(smc->hasDefaultCollection(SpecialMailCollections::Outbox));
0310     QCOMPARE(smc->defaultCollection(SpecialMailCollections::Outbox), outbox);
0311     QCOMPARE(smct->_t_knownResourceCount(), 1);
0312     QCOMPARE(smct->_t_knownFolderCount(), 1);
0313     QCOMPARE(spy.count(), 1);
0314     QCOMPARE(defSpy.count(), 1);
0315 
0316     // Delete the collection. LF should watch for that.
0317     CollectionDeleteJob *djob = new CollectionDeleteJob(outbox, this);
0318     AKVERIFYEXEC(djob);
0319     QTest::qWait(100);
0320     QVERIFY(!smc->hasDefaultCollection(SpecialMailCollections::Outbox));
0321     QCOMPARE(smct->_t_knownResourceCount(), 0);
0322     QCOMPARE(smct->_t_knownFolderCount(), 0);
0323     QCOMPARE(spy.count(), 2);
0324     QCOMPARE(defSpy.count(), 2);
0325 }
0326 
0327 void LocalFoldersTest::testBatchRegister()
0328 {
0329     SpecialMailCollections *smc = SpecialMailCollections::self();
0330     SpecialCollections *sc = smc;
0331     SpecialMailCollectionsTesting *smct = SpecialMailCollectionsTesting::_t_self();
0332     Q_ASSERT(smc);
0333     Q_ASSERT(smct);
0334     QSignalSpy spy(smc, &SpecialMailCollections::collectionsChanged);
0335     QSignalSpy defSpy(smc, &SpecialMailCollections::defaultCollectionsChanged);
0336     QVERIFY(spy.isValid());
0337     QVERIFY(defSpy.isValid());
0338 
0339     // Set the default resource. LF should have no folders.
0340     smct->_t_setDefaultResourceId(res1.resource());
0341     QCOMPARE(sc->d->defaultResource().identifier(), res1.resource());
0342     QCOMPARE(smct->_t_knownResourceCount(), 0);
0343     QCOMPARE(smct->_t_knownFolderCount(), 0);
0344 
0345     // Manually create an Outbox collection.
0346     Collection outbox;
0347     outbox.setName(QLatin1StringView("my_outbox"));
0348     outbox.setParentCollection(res1);
0349     outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0350     CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0351     AKVERIFYEXEC(cjob);
0352     outbox = cjob->collection();
0353 
0354     // Manually create a Drafts collection.
0355     Collection drafts;
0356     drafts.setName(QLatin1StringView("my_drafts"));
0357     drafts.setParentCollection(res1);
0358     drafts.addAttribute(new SpecialCollectionAttribute("drafts"));
0359     cjob = new CollectionCreateJob(drafts, this);
0360     AKVERIFYEXEC(cjob);
0361     drafts = cjob->collection();
0362 
0363     // LF should still have no folders, since the folders were not registered.
0364     QCOMPARE(smct->_t_knownResourceCount(), 0);
0365     QCOMPARE(smct->_t_knownFolderCount(), 0);
0366     QCOMPARE(spy.count(), 0);
0367     QCOMPARE(defSpy.count(), 0);
0368 
0369     // Register the folders in batch mode.
0370     smct->_t_beginBatchRegister();
0371     bool ok = smc->registerCollection(SpecialMailCollections::Outbox, outbox);
0372     QVERIFY(ok);
0373     QVERIFY(smc->hasDefaultCollection(SpecialMailCollections::Outbox));
0374     QCOMPARE(smc->defaultCollection(SpecialMailCollections::Outbox), outbox);
0375     QCOMPARE(smct->_t_knownResourceCount(), 1);
0376     QCOMPARE(smct->_t_knownFolderCount(), 1);
0377     QCOMPARE(spy.count(), 0);
0378     QCOMPARE(defSpy.count(), 0);
0379     ok = smc->registerCollection(SpecialMailCollections::Drafts, drafts);
0380     QVERIFY(ok);
0381     QVERIFY(smc->hasDefaultCollection(SpecialMailCollections::Drafts));
0382     QCOMPARE(smc->defaultCollection(SpecialMailCollections::Drafts), drafts);
0383     QCOMPARE(smct->_t_knownResourceCount(), 1);
0384     QCOMPARE(smct->_t_knownFolderCount(), 2);
0385     QCOMPARE(spy.count(), 0);
0386     QCOMPARE(defSpy.count(), 0);
0387     smct->_t_endBatchRegister();
0388     QCOMPARE(smct->_t_knownResourceCount(), 1);
0389     QCOMPARE(smct->_t_knownFolderCount(), 2);
0390     QCOMPARE(spy.count(), 1);
0391     QCOMPARE(defSpy.count(), 1);
0392 
0393     // Forget all folders in the default resource.
0394     smct->_t_forgetFoldersForResource(sc->d->defaultResource().identifier());
0395     QCOMPARE(smc->hasDefaultCollection(SpecialMailCollections::Outbox), false);
0396     QCOMPARE(smc->hasDefaultCollection(SpecialMailCollections::Drafts), false);
0397     QCOMPARE(smct->_t_knownResourceCount(), 0);
0398     QCOMPARE(smct->_t_knownFolderCount(), 0);
0399     QCOMPARE(spy.count(), 2);
0400     QCOMPARE(defSpy.count(), 2);
0401 
0402     // Delete the collections.
0403     CollectionDeleteJob *djob = new CollectionDeleteJob(outbox, this);
0404     AKVERIFYEXEC(djob);
0405     djob = new CollectionDeleteJob(drafts, this);
0406     AKVERIFYEXEC(djob);
0407 }
0408 
0409 void LocalFoldersTest::testResourceScanErrors()
0410 {
0411     // Job fails if no resourceId is given.
0412     ResourceScanJob *resjob = new ResourceScanJob(QString(), Settings::self(), this);
0413     QVERIFY(!resjob->exec());
0414 }
0415 
0416 void LocalFoldersTest::testResourceScan()
0417 {
0418     // Verify that res1 has no collections.
0419     {
0420         CollectionFetchJob *fjob = new CollectionFetchJob(res1, CollectionFetchJob::Recursive, this);
0421         AKVERIFYEXEC(fjob);
0422         QCOMPARE(fjob->collections().count(), 0);
0423     }
0424 
0425     // Manually create an Outbox collection.
0426     Collection outbox;
0427     {
0428         outbox.setName(QLatin1StringView("my_outbox"));
0429         outbox.setParentCollection(res1);
0430         outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0431         CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0432         AKVERIFYEXEC(cjob);
0433         outbox = cjob->collection();
0434     }
0435 
0436     // Manually create a Drafts collection.
0437     Collection drafts;
0438     {
0439         drafts.setName(QLatin1StringView("my_drafts"));
0440         drafts.setParentCollection(res1);
0441         drafts.addAttribute(new SpecialCollectionAttribute("drafts"));
0442         CollectionCreateJob *cjob = new CollectionCreateJob(drafts, this);
0443         AKVERIFYEXEC(cjob);
0444         drafts = cjob->collection();
0445     }
0446 
0447     // Manually create a non-LocalFolder collection.
0448     Collection intruder;
0449     {
0450         intruder.setName(QLatin1StringView("intruder"));
0451         intruder.setParentCollection(res1);
0452         CollectionCreateJob *cjob = new CollectionCreateJob(intruder, this);
0453         AKVERIFYEXEC(cjob);
0454         intruder = cjob->collection();
0455     }
0456 
0457     // Verify that the collections have been created properly.
0458     {
0459         CollectionFetchJob *fjob = new CollectionFetchJob(res1, CollectionFetchJob::Recursive, this);
0460         AKVERIFYEXEC(fjob);
0461         QCOMPARE(fjob->collections().count(), 3);
0462     }
0463 
0464     // Test that ResourceScanJob finds everything correctly.
0465     ResourceScanJob *resjob = new ResourceScanJob(res1.resource(), Settings::self(), this);
0466     AKVERIFYEXEC(resjob);
0467     QCOMPARE(resjob->rootResourceCollection(), res1);
0468     const Collection::List folders = resjob->specialCollections();
0469     QCOMPARE(folders.count(), 2);
0470     QVERIFY(folders.contains(outbox));
0471     QVERIFY(folders.contains(drafts));
0472 
0473     // Clean up after ourselves.
0474     CollectionDeleteJob *djob = new CollectionDeleteJob(outbox, this);
0475     AKVERIFYEXEC(djob);
0476     djob = new CollectionDeleteJob(drafts, this);
0477     AKVERIFYEXEC(djob);
0478     djob = new CollectionDeleteJob(intruder, this);
0479     AKVERIFYEXEC(djob);
0480 
0481     SpecialMailCollections::self()->destroy();
0482 }
0483 
0484 void LocalFoldersTest::testDefaultResourceJob()
0485 {
0486     SpecialMailCollectionsTesting *scmt = SpecialMailCollectionsTesting::_t_self();
0487     scmt->_t_setDefaultResourceId(QLatin1StringView("akonadi_maildir_resource"));
0488 
0489     // Initially the default maildir does not exist.
0490     QVERIFY(!QFile::exists(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/local-mail")));
0491 
0492     // Run the job.
0493     Collection maildirRoot;
0494     QString resourceId;
0495     {
0496         DefaultResourceJob *resjob = new DefaultResourceJob(Settings::self(), this);
0497         resjob->setDefaultResourceType(QLatin1StringView("akonadi_maildir_resource"));
0498 
0499         QVariantMap options;
0500         options.insert(QLatin1StringView("Name"), i18nc("local mail folder", "Local Folders"));
0501         options.insert(QLatin1StringView("Path"),
0502                        QString(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/local-mail")));
0503         resjob->setDefaultResourceOptions(options);
0504         resjob->setTypes(mDisplayNameMap.keys());
0505         resjob->setNameForTypeMap(mDisplayNameMap);
0506         resjob->setIconForTypeMap(mIconNameMap);
0507 
0508         AKVERIFYEXEC(resjob);
0509         resourceId = resjob->resourceId();
0510         const Collection::List folders = resjob->specialCollections();
0511         QCOMPARE(folders.count(), 1);
0512         maildirRoot = folders.first();
0513         QVERIFY(maildirRoot.hasAttribute<SpecialCollectionAttribute>());
0514         QCOMPARE(maildirRoot.attribute<SpecialCollectionAttribute>()->collectionType(), QByteArray("local-mail"));
0515     }
0516 
0517     // The maildir should exist now.
0518     QVERIFY(QFile::exists(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/local-mail")));
0519 
0520     // Create a LocalFolder in the default resource.
0521     Collection outbox;
0522     {
0523         outbox.setName(QLatin1StringView("outbox"));
0524         outbox.setParentCollection(maildirRoot);
0525         outbox.addAttribute(new SpecialCollectionAttribute("outbox"));
0526         CollectionCreateJob *cjob = new CollectionCreateJob(outbox, this);
0527         AKVERIFYEXEC(cjob);
0528         outbox = cjob->collection();
0529 
0530         // Wait for the maildir resource to actually create the folder on disk...
0531         // (needed in testRecoverDefaultResource())
0532         QTest::qWait(500);
0533     }
0534 
0535     // Run the job again.
0536     {
0537         DefaultResourceJob *resjob = new DefaultResourceJob(Settings::self(), this);
0538         resjob->setDefaultResourceType(QLatin1StringView("akonadi_maildir_resource"));
0539 
0540         QVariantMap options;
0541         options.insert(QLatin1StringView("Name"), i18nc("local mail folder", "Local Folders"));
0542         options.insert(QLatin1StringView("Path"),
0543                        QString(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/local-mail")));
0544         resjob->setDefaultResourceOptions(options);
0545         resjob->setTypes(mDisplayNameMap.keys());
0546         resjob->setNameForTypeMap(mDisplayNameMap);
0547         resjob->setIconForTypeMap(mIconNameMap);
0548 
0549         AKVERIFYEXEC(resjob);
0550         QCOMPARE(resourceId, resjob->resourceId()); // Did not mistakenly create another resource.
0551         const Collection::List folders = resjob->specialCollections();
0552         QCOMPARE(folders.count(), 2);
0553         QVERIFY(folders.contains(maildirRoot));
0554         QVERIFY(folders.contains(outbox));
0555     }
0556 }
0557 
0558 void LocalFoldersTest::testRecoverDefaultResource()
0559 {
0560     // The maildirs should exist (created in testDefaultResourceJob).
0561     const QString xdgPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/');
0562     const QString rootPath = xdgPath + QLatin1StringView("local-mail");
0563     const QString outboxPath = xdgPath + QString::fromLatin1(".%1.directory/%2").arg(QLatin1StringView("local-mail")).arg(QLatin1StringView("outbox"));
0564     QVERIFY(QFile::exists(rootPath));
0565     QVERIFY(QFile::exists(outboxPath));
0566 
0567     // Kill the default resource.
0568     const QString oldResourceId = static_cast<SpecialCollections *>(SpecialMailCollections::self())->d->defaultResource().identifier();
0569     const AgentInstance resource = AgentManager::self()->instance(oldResourceId);
0570     QVERIFY(resource.isValid());
0571     AgentManager::self()->removeInstance(resource);
0572     QTest::qWait(100);
0573 
0574     // Run the DefaultResourceJob now. It should recover the Root and Outbox folders
0575     // created in testDefaultResourceJob.
0576     {
0577         DefaultResourceJob *resjob = new DefaultResourceJob(Settings::self(), this);
0578         resjob->setDefaultResourceType(QLatin1StringView("akonadi_maildir_resource"));
0579 
0580         QVariantMap options;
0581         options.insert(QLatin1StringView("Name"), i18nc("local mail folder", "Local Folders"));
0582         options.insert(QLatin1StringView("Path"),
0583                        QString(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1StringView("/local-mail")));
0584         resjob->setDefaultResourceOptions(options);
0585         resjob->setTypes(mDisplayNameMap.keys());
0586         resjob->setNameForTypeMap(mDisplayNameMap);
0587         resjob->setIconForTypeMap(mIconNameMap);
0588 
0589         AKVERIFYEXEC(resjob);
0590         QVERIFY(resjob->resourceId() != oldResourceId); // Created another resource.
0591         Collection::List folders = resjob->specialCollections();
0592         QCOMPARE(folders.count(), 2);
0593 
0594         // Reorder the folders.
0595         if (folders.first().parentCollection() != Collection::root()) {
0596             folders.move(1, 0);
0597         }
0598 
0599         // The first folder should be the Root.
0600         {
0601             Collection col = folders[0];
0602             QCOMPARE(col.name(), QLatin1StringView("Local Folders"));
0603             QVERIFY(col.hasAttribute<SpecialCollectionAttribute>());
0604             QCOMPARE(col.attribute<SpecialCollectionAttribute>()->collectionType(), QByteArray("local-mail"));
0605         }
0606 
0607         // The second folder should be the Outbox.
0608         {
0609             Collection col = folders[1];
0610             QCOMPARE(col.name(), QLatin1StringView("outbox"));
0611             QVERIFY(col.hasAttribute<SpecialCollectionAttribute>());
0612             QCOMPARE(col.attribute<SpecialCollectionAttribute>()->collectionType(), QByteArray("outbox"));
0613         }
0614     }
0615 }
0616 
0617 QTEST_AKONADIMAIN(LocalFoldersTest)
0618 
0619 #include "moc_localfolderstest.cpp"