File indexing completed on 2024-11-10 04:40:09
0001 /* 0002 SPDX-FileCopyrightText: 2006 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "collectionjobtest.h" 0008 0009 #include <sys/types.h> 0010 0011 #include "qtest_akonadi.h" 0012 #include "testattribute.h" 0013 0014 #include "agentinstance.h" 0015 #include "agentmanager.h" 0016 #include "attributefactory.h" 0017 #include "cachepolicy.h" 0018 #include "collection.h" 0019 #include "collectioncreatejob.h" 0020 #include "collectiondeletejob.h" 0021 #include "collectionfetchjob.h" 0022 #include "collectionfetchscope.h" 0023 #include "collectionmodifyjob.h" 0024 #include "collectionstatistics.h" 0025 #include "collectionstatisticsjob.h" 0026 #include "collectionutils.h" 0027 #include "control.h" 0028 #include "item.h" 0029 #include "resourceselectjob_p.h" 0030 0031 using namespace Akonadi; 0032 0033 QTEST_AKONADIMAIN(CollectionJobTest) 0034 0035 void CollectionJobTest::initTestCase() 0036 { 0037 qRegisterMetaType<Akonadi::Collection::List>(); 0038 AttributeFactory::registerAttribute<TestAttribute>(); 0039 AkonadiTest::checkTestIsIsolated(); 0040 Control::start(); 0041 AkonadiTest::setAllResourcesOffline(); 0042 } 0043 0044 static Collection findCol(const Collection::List &list, const QString &name) 0045 { 0046 for (const Collection &col : list) { 0047 if (col.name() == name) { 0048 return col; 0049 } 0050 } 0051 return Collection(); 0052 } 0053 0054 // list compare which ignores the order 0055 template<class T> 0056 static void compareLists(const QList<T> &l1, const QList<T> &l2) 0057 { 0058 QCOMPARE(l1.count(), l2.count()); 0059 for (const T &entry : l1) { 0060 QVERIFY(l2.contains(entry)); 0061 } 0062 } 0063 0064 template<typename T> 0065 static T *extractAttribute(const QList<Attribute *> &attrs) 0066 { 0067 T dummy; 0068 for (Attribute *attr : attrs) { 0069 if (attr->type() == dummy.type()) { 0070 return dynamic_cast<T *>(attr); 0071 } 0072 } 0073 return 0; 0074 } 0075 0076 static Collection::Id res1ColId = 6; // -1; 0077 static Collection::Id res2ColId = 7; //-1; 0078 static Collection::Id res3ColId = -1; 0079 static Collection::Id searchColId = -1; 0080 0081 void CollectionJobTest::testTopLevelList() 0082 { 0083 // non-recursive top-level list 0084 auto job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); 0085 AKVERIFYEXEC(job); 0086 Collection::List list = job->collections(); 0087 0088 // check if everything is there and has the correct types and attributes 0089 QCOMPARE(list.count(), 4); 0090 Collection col; 0091 0092 col = findCol(list, QStringLiteral("res1")); 0093 QVERIFY(col.isValid()); 0094 res1ColId = col.id(); // for the next test 0095 QVERIFY(res1ColId > 0); 0096 QVERIFY(CollectionUtils::isResource(col)); 0097 QCOMPARE(col.parentCollection(), Collection::root()); 0098 QCOMPARE(col.resource(), QStringLiteral("akonadi_knut_resource_0")); 0099 0100 QVERIFY(findCol(list, QStringLiteral("res2")).isValid()); 0101 res2ColId = findCol(list, QStringLiteral("res2")).id(); 0102 QVERIFY(res2ColId > 0); 0103 QVERIFY(findCol(list, QStringLiteral("res3")).isValid()); 0104 res3ColId = findCol(list, QStringLiteral("res3")).id(); 0105 QVERIFY(res3ColId > 0); 0106 0107 col = findCol(list, QStringLiteral("Search")); 0108 searchColId = col.id(); 0109 QVERIFY(col.isValid()); 0110 QVERIFY(CollectionUtils::isVirtualParent(col)); 0111 QCOMPARE(col.resource(), QStringLiteral("akonadi_search_resource")); 0112 } 0113 0114 void CollectionJobTest::testFolderList() 0115 { 0116 // recursive list of physical folders 0117 auto job = new CollectionFetchJob(Collection(res1ColId), CollectionFetchJob::Recursive); 0118 QSignalSpy spy(job, &CollectionFetchJob::collectionsReceived); 0119 QVERIFY(spy.isValid()); 0120 AKVERIFYEXEC(job); 0121 Collection::List list = job->collections(); 0122 0123 int count = 0; 0124 for (int i = 0; i < spy.count(); ++i) { 0125 auto l = spy[i][0].value<Akonadi::Collection::List>(); 0126 for (int j = 0; j < l.count(); ++j) { 0127 QVERIFY(list.count() > count + j); 0128 QCOMPARE(list[count + j].id(), l[j].id()); 0129 } 0130 count += l.count(); 0131 } 0132 QCOMPARE(count, list.count()); 0133 0134 // check if everything is there 0135 QCOMPARE(list.count(), 4); 0136 Collection col; 0137 QStringList contentTypes; 0138 0139 col = findCol(list, QStringLiteral("foo")); 0140 QVERIFY(col.isValid()); 0141 QCOMPARE(col.parentCollection().id(), res1ColId); 0142 QVERIFY(CollectionUtils::isFolder(col)); 0143 contentTypes << QStringLiteral("message/rfc822") << QStringLiteral("text/calendar") << QStringLiteral("text/directory") 0144 << QStringLiteral("application/octet-stream") << QStringLiteral("inode/directory"); 0145 compareLists(col.contentMimeTypes(), contentTypes); 0146 0147 QVERIFY(findCol(list, QStringLiteral("bar")).isValid()); 0148 QCOMPARE(findCol(list, QStringLiteral("bar")).parentCollection(), col); 0149 QVERIFY(findCol(list, QStringLiteral("bla")).isValid()); 0150 } 0151 0152 class ResultSignalTester : public QObject 0153 { 0154 Q_OBJECT 0155 public: 0156 QStringList receivedSignals; 0157 public Q_SLOTS: 0158 void onCollectionsReceived(const Akonadi::Collection::List & /*unused*/) 0159 { 0160 receivedSignals << QStringLiteral("collectionsReceived"); 0161 } 0162 0163 void onCollectionRetrievalDone(KJob * /*unused*/) 0164 { 0165 receivedSignals << QStringLiteral("result"); 0166 } 0167 }; 0168 0169 void CollectionJobTest::testSignalOrder() 0170 { 0171 Akonadi::Collection::List toFetch; 0172 toFetch << Collection(res1ColId); 0173 toFetch << Collection(res2ColId); 0174 auto job = new CollectionFetchJob(toFetch, CollectionFetchJob::Recursive); 0175 ResultSignalTester spy; 0176 connect(job, &CollectionFetchJob::collectionsReceived, &spy, &ResultSignalTester::onCollectionsReceived); 0177 connect(job, &KJob::result, &spy, &ResultSignalTester::onCollectionRetrievalDone); 0178 AKVERIFYEXEC(job); 0179 0180 QCOMPARE(spy.receivedSignals.size(), 2); 0181 QCOMPARE(spy.receivedSignals.at(0), QStringLiteral("collectionsReceived")); 0182 QCOMPARE(spy.receivedSignals.at(1), QStringLiteral("result")); 0183 } 0184 0185 void CollectionJobTest::testNonRecursiveFolderList() 0186 { 0187 auto job = new CollectionFetchJob(Collection(res1ColId), CollectionFetchJob::Base); 0188 AKVERIFYEXEC(job); 0189 Collection::List list = job->collections(); 0190 0191 QCOMPARE(list.count(), 1); 0192 QVERIFY(findCol(list, QStringLiteral("res1")).isValid()); 0193 } 0194 0195 void CollectionJobTest::testEmptyFolderList() 0196 { 0197 auto job = new CollectionFetchJob(Collection(res3ColId), CollectionFetchJob::FirstLevel); 0198 AKVERIFYEXEC(job); 0199 Collection::List list = job->collections(); 0200 0201 QCOMPARE(list.count(), 0); 0202 } 0203 0204 void CollectionJobTest::testSearchFolderList() 0205 { 0206 auto job = new CollectionFetchJob(Collection(searchColId), CollectionFetchJob::FirstLevel); 0207 AKVERIFYEXEC(job); 0208 Collection::List list = job->collections(); 0209 0210 QCOMPARE(list.count(), 0); 0211 } 0212 0213 void CollectionJobTest::testResourceFolderList() 0214 { 0215 // non-existing resource 0216 auto job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::FirstLevel); 0217 job->fetchScope().setResource(QStringLiteral("i_dont_exist")); 0218 QVERIFY(!job->exec()); 0219 0220 // recursive listing of all collections of an existing resource 0221 job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); 0222 job->fetchScope().setResource(QStringLiteral("akonadi_knut_resource_0")); 0223 AKVERIFYEXEC(job); 0224 0225 Collection::List list = job->collections(); 0226 QCOMPARE(list.count(), 5); 0227 QVERIFY(findCol(list, QStringLiteral("res1")).isValid()); 0228 QVERIFY(findCol(list, QStringLiteral("foo")).isValid()); 0229 QVERIFY(findCol(list, QStringLiteral("bar")).isValid()); 0230 QVERIFY(findCol(list, QStringLiteral("bla")).isValid()); 0231 int fooId = findCol(list, QStringLiteral("foo")).id(); 0232 0233 // limited listing of a resource 0234 job = new CollectionFetchJob(Collection(fooId), CollectionFetchJob::Recursive); 0235 job->fetchScope().setResource(QStringLiteral("akonadi_knut_resource_0")); 0236 AKVERIFYEXEC(job); 0237 0238 list = job->collections(); 0239 QCOMPARE(list.count(), 3); 0240 QVERIFY(findCol(list, QStringLiteral("bar")).isValid()); 0241 QVERIFY(findCol(list, QStringLiteral("bla")).isValid()); 0242 } 0243 0244 void CollectionJobTest::testMimeTypeFilter() 0245 { 0246 auto job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive); 0247 job->fetchScope().setContentMimeTypes(QStringList() << QStringLiteral("message/rfc822")); 0248 AKVERIFYEXEC(job); 0249 0250 Collection::List list = job->collections(); 0251 QCOMPARE(list.count(), 2); 0252 QVERIFY(findCol(list, QStringLiteral("res1")).isValid()); 0253 QVERIFY(findCol(list, QStringLiteral("foo")).isValid()); 0254 int fooId = findCol(list, QStringLiteral("foo")).id(); 0255 0256 // limited listing of a resource 0257 job = new CollectionFetchJob(Collection(fooId), CollectionFetchJob::Recursive); 0258 job->fetchScope().setContentMimeTypes(QStringList() << QStringLiteral("message/rfc822")); 0259 AKVERIFYEXEC(job); 0260 0261 list = job->collections(); 0262 QCOMPARE(list.count(), 0); 0263 0264 // non-existing mimetype 0265 job = new CollectionFetchJob(Collection::root(), CollectionFetchJob::Recursive, this); 0266 job->fetchScope().setContentMimeTypes(QStringList() << QStringLiteral("something/non-existing")); 0267 AKVERIFYEXEC(job); 0268 QCOMPARE(job->collections().size(), 0); 0269 } 0270 0271 void CollectionJobTest::testCreateDeleteFolder_data() 0272 { 0273 QTest::addColumn<Collection>("collection"); 0274 QTest::addColumn<bool>("creatable"); 0275 0276 Collection col; 0277 QTest::newRow("empty") << col << false; 0278 col.setName(QStringLiteral("new folder")); 0279 col.parentCollection().setId(res3ColId); 0280 QTest::newRow("simple") << col << true; 0281 0282 col.parentCollection().setId(res3ColId); 0283 col.setName(QStringLiteral("foo")); 0284 QTest::newRow("existing in different resource") << col << true; 0285 0286 col.setName(QStringLiteral("mail folder")); 0287 QStringList mimeTypes; 0288 mimeTypes << QStringLiteral("inode/directory") << QStringLiteral("message/rfc822"); 0289 col.setContentMimeTypes(mimeTypes); 0290 col.setRemoteId(QStringLiteral("remote id")); 0291 CachePolicy policy; 0292 policy.setInheritFromParent(false); 0293 policy.setIntervalCheckTime(60); 0294 policy.setLocalParts({QStringLiteral("PLD:ENVELOPE")}); 0295 policy.setSyncOnDemand(true); 0296 policy.setCacheTimeout(120); 0297 col.setCachePolicy(policy); 0298 QTest::newRow("complex") << col << true; 0299 0300 col = Collection(); 0301 col.setName(QStringLiteral("New Folder")); 0302 col.parentCollection().setId(searchColId); 0303 QTest::newRow("search folder") << col << false; 0304 0305 col.parentCollection().setId(res2ColId); 0306 col.setName(QStringLiteral("foo2")); 0307 QTest::newRow("already existing") << col << false; 0308 0309 col.parentCollection().setId(res2ColId); // Sibling of collection 'foo2' 0310 col.setName(QStringLiteral("foo2 ")); 0311 QTest::newRow("name of an sibling with an additional ending space") << col << true; 0312 0313 col.setName(QStringLiteral("Bla")); 0314 col.parentCollection().setId(2); 0315 QTest::newRow("already existing with different case") << col << true; 0316 0317 auto resolver = new CollectionPathResolver(QStringLiteral("res2/foo2"), this); 0318 AKVERIFYEXEC(resolver); 0319 col.parentCollection().setId(resolver->collection()); 0320 col.setName(QStringLiteral("new folder")); 0321 QTest::newRow("parent noinferior") << col << false; 0322 0323 col.parentCollection().setId(INT_MAX); 0324 QTest::newRow("missing parent") << col << false; 0325 0326 col = Collection(); 0327 col.setName(QStringLiteral("rid parent")); 0328 col.parentCollection().setRemoteId(QStringLiteral("8")); 0329 QTest::newRow("rid parent") << col << false; // missing resource context 0330 } 0331 0332 void CollectionJobTest::testCreateDeleteFolder() 0333 { 0334 QFETCH(Collection, collection); 0335 QFETCH(bool, creatable); 0336 0337 auto createJob = new CollectionCreateJob(collection, this); 0338 QCOMPARE(createJob->exec(), creatable); 0339 if (!creatable) { 0340 return; 0341 } 0342 0343 Collection createdCol = createJob->collection(); 0344 QVERIFY(createdCol.isValid()); 0345 QCOMPARE(createdCol.name(), collection.name()); 0346 QCOMPARE(createdCol.parentCollection(), collection.parentCollection()); 0347 QCOMPARE(createdCol.remoteId(), collection.remoteId()); 0348 QCOMPARE(createdCol.cachePolicy(), collection.cachePolicy()); 0349 0350 auto listJob = new CollectionFetchJob(collection.parentCollection(), CollectionFetchJob::FirstLevel, this); 0351 AKVERIFYEXEC(listJob); 0352 Collection listedCol = findCol(listJob->collections(), collection.name()); 0353 QCOMPARE(listedCol, createdCol); 0354 QCOMPARE(listedCol.remoteId(), collection.remoteId()); 0355 QCOMPARE(listedCol.cachePolicy(), collection.cachePolicy()); 0356 0357 // fetch parent to compare inherited collection properties 0358 Collection parentCol = Collection::root(); 0359 if (collection.parentCollection().isValid()) { 0360 auto newListJob = new CollectionFetchJob(collection.parentCollection(), CollectionFetchJob::Base, this); 0361 AKVERIFYEXEC(newListJob); 0362 QCOMPARE(newListJob->collections().count(), 1); 0363 parentCol = newListJob->collections().first(); 0364 } 0365 0366 if (collection.contentMimeTypes().isEmpty()) { 0367 compareLists(listedCol.contentMimeTypes(), parentCol.contentMimeTypes()); 0368 } else { 0369 compareLists(listedCol.contentMimeTypes(), collection.contentMimeTypes()); 0370 } 0371 0372 if (collection.resource().isEmpty()) { 0373 QCOMPARE(listedCol.resource(), parentCol.resource()); 0374 } else { 0375 QCOMPARE(listedCol.resource(), collection.resource()); 0376 } 0377 0378 auto delJob = new CollectionDeleteJob(createdCol, this); 0379 AKVERIFYEXEC(delJob); 0380 0381 listJob = new CollectionFetchJob(collection.parentCollection(), CollectionFetchJob::FirstLevel, this); 0382 AKVERIFYEXEC(listJob); 0383 QVERIFY(!findCol(listJob->collections(), collection.name()).isValid()); 0384 } 0385 0386 void CollectionJobTest::testIllegalDeleteFolder() 0387 { 0388 // non-existing folder 0389 auto del = new CollectionDeleteJob(Collection(INT_MAX), this); 0390 QVERIFY(!del->exec()); 0391 0392 // root 0393 del = new CollectionDeleteJob(Collection::root(), this); 0394 QVERIFY(!del->exec()); 0395 } 0396 0397 void CollectionJobTest::testStatistics() 0398 { 0399 // empty folder 0400 auto statistics = new CollectionStatisticsJob(Collection(res1ColId), this); 0401 AKVERIFYEXEC(statistics); 0402 0403 CollectionStatistics s = statistics->statistics(); 0404 QCOMPARE(s.count(), 0LL); 0405 QCOMPARE(s.unreadCount(), 0LL); 0406 0407 // folder with attributes and content 0408 auto resolver = new CollectionPathResolver(QStringLiteral("res1/foo"), this); 0409 AKVERIFYEXEC(resolver); 0410 statistics = new CollectionStatisticsJob(Collection(resolver->collection()), this); 0411 AKVERIFYEXEC(statistics); 0412 0413 s = statistics->statistics(); 0414 QCOMPARE(s.count(), 15LL); 0415 QCOMPARE(s.unreadCount(), 14LL); 0416 } 0417 0418 void CollectionJobTest::testModify_data() 0419 { 0420 QTest::addColumn<qint64>("uid"); 0421 QTest::addColumn<QString>("rid"); 0422 0423 QTest::newRow("uid") << AkonadiTest::collectionIdFromPath(QStringLiteral("res1/foo")) << QString(); 0424 QTest::newRow("rid") << -1LL << QStringLiteral("10"); 0425 } 0426 0427 #define RESET_COLLECTION_ID \ 0428 col.setId(uid); \ 0429 if (!rid.isEmpty()) \ 0430 col.setRemoteId(rid) 0431 0432 void CollectionJobTest::testModify() 0433 { 0434 QFETCH(qint64, uid); 0435 QFETCH(QString, rid); 0436 0437 if (!rid.isEmpty()) { 0438 auto rjob = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_0")); 0439 AKVERIFYEXEC(rjob); 0440 } 0441 0442 const QStringList reference = {QStringLiteral("text/calendar"), 0443 QStringLiteral("text/directory"), 0444 QStringLiteral("message/rfc822"), 0445 QStringLiteral("application/octet-stream"), 0446 QStringLiteral("inode/directory")}; 0447 0448 Collection col; 0449 RESET_COLLECTION_ID; 0450 0451 // test noop modify 0452 auto mod = new CollectionModifyJob(col, this); 0453 AKVERIFYEXEC(mod); 0454 0455 auto ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0456 AKVERIFYEXEC(ljob); 0457 QCOMPARE(ljob->collections().count(), 1); 0458 col = ljob->collections().first(); 0459 compareLists(col.contentMimeTypes(), reference); 0460 0461 // test clearing content types 0462 RESET_COLLECTION_ID; 0463 col.setContentMimeTypes(QStringList()); 0464 mod = new CollectionModifyJob(col, this); 0465 AKVERIFYEXEC(mod); 0466 0467 ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0468 AKVERIFYEXEC(ljob); 0469 QCOMPARE(ljob->collections().count(), 1); 0470 col = ljob->collections().first(); 0471 QVERIFY(col.contentMimeTypes().isEmpty()); 0472 0473 // test setting contnet types 0474 RESET_COLLECTION_ID; 0475 col.setContentMimeTypes(reference); 0476 mod = new CollectionModifyJob(col, this); 0477 AKVERIFYEXEC(mod); 0478 0479 ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0480 AKVERIFYEXEC(ljob); 0481 QCOMPARE(ljob->collections().count(), 1); 0482 col = ljob->collections().first(); 0483 compareLists(col.contentMimeTypes(), reference); 0484 0485 // add attribute 0486 RESET_COLLECTION_ID; 0487 col.attribute<TestAttribute>(Collection::AddIfMissing)->data = "new"; 0488 mod = new CollectionModifyJob(col, this); 0489 AKVERIFYEXEC(mod); 0490 0491 ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0492 AKVERIFYEXEC(ljob); 0493 QVERIFY(ljob->collections().first().hasAttribute<TestAttribute>()); 0494 QCOMPARE(ljob->collections().first().attribute<TestAttribute>()->data, QByteArray("new")); 0495 0496 // modify existing attribute 0497 RESET_COLLECTION_ID; 0498 col.attribute<TestAttribute>()->data = "modified"; 0499 mod = new CollectionModifyJob(col, this); 0500 AKVERIFYEXEC(mod); 0501 0502 ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0503 AKVERIFYEXEC(ljob); 0504 QVERIFY(ljob->collections().first().hasAttribute<TestAttribute>()); 0505 QCOMPARE(ljob->collections().first().attribute<TestAttribute>()->data, QByteArray("modified")); 0506 0507 // renaming 0508 RESET_COLLECTION_ID; 0509 col.setName(QStringLiteral("foo (renamed)")); 0510 mod = new CollectionModifyJob(col, this); 0511 AKVERIFYEXEC(mod); 0512 0513 ljob = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0514 AKVERIFYEXEC(ljob); 0515 QCOMPARE(ljob->collections().count(), 1); 0516 col = ljob->collections().first(); 0517 QCOMPARE(col.name(), QStringLiteral("foo (renamed)")); 0518 0519 RESET_COLLECTION_ID; 0520 col.setName(QStringLiteral("foo")); 0521 mod = new CollectionModifyJob(col, this); 0522 AKVERIFYEXEC(mod); 0523 } 0524 0525 #undef RESET_COLLECTION_ID 0526 0527 void CollectionJobTest::testIllegalModify() 0528 { 0529 // non-existing collection 0530 Collection col(INT_MAX); 0531 col.parentCollection().setId(res1ColId); 0532 auto mod = new CollectionModifyJob(col, this); 0533 QVERIFY(!mod->exec()); 0534 0535 // rename to already existing name 0536 col = Collection(res1ColId); 0537 col.setName(QStringLiteral("res2")); 0538 mod = new CollectionModifyJob(col, this); 0539 QVERIFY(!mod->exec()); 0540 } 0541 0542 void CollectionJobTest::testUtf8CollectionName_data() 0543 { 0544 QTest::addColumn<QString>("folderName"); 0545 0546 QTest::newRow("Umlaut") << QString::fromUtf8("ä"); 0547 QTest::newRow("Garbage") << QString::fromUtf8("đ→³}đþøæſð"); 0548 QTest::newRow("Utf8") << QString::fromUtf8("日本語"); 0549 } 0550 0551 void CollectionJobTest::testUtf8CollectionName() 0552 { 0553 QFETCH(QString, folderName); 0554 0555 // create collection 0556 Collection col; 0557 col.parentCollection().setId(res3ColId); 0558 col.setName(folderName); 0559 auto create = new CollectionCreateJob(col, this); 0560 AKVERIFYEXEC(create); 0561 col = create->collection(); 0562 QVERIFY(col.isValid()); 0563 QCOMPARE(col.name(), folderName); 0564 0565 // list parent 0566 auto list = new CollectionFetchJob(Collection(res3ColId), CollectionFetchJob::Recursive, this); 0567 AKVERIFYEXEC(list); 0568 QCOMPARE(list->collections().count(), 1); 0569 QCOMPARE(list->collections().first(), col); 0570 QCOMPARE(list->collections().first().name(), col.name()); 0571 0572 // modify collection 0573 col.setContentMimeTypes({QStringLiteral("message/rfc822")}); 0574 auto modify = new CollectionModifyJob(col, this); 0575 AKVERIFYEXEC(modify); 0576 0577 // collection statistics 0578 auto statistics = new CollectionStatisticsJob(col, this); 0579 AKVERIFYEXEC(statistics); 0580 CollectionStatistics s = statistics->statistics(); 0581 QCOMPARE(s.count(), 0LL); 0582 QCOMPARE(s.unreadCount(), 0LL); 0583 0584 // delete collection 0585 auto del = new CollectionDeleteJob(col, this); 0586 AKVERIFYEXEC(del); 0587 } 0588 0589 void CollectionJobTest::testMultiList() 0590 { 0591 Collection::List req; 0592 req << Collection(res1ColId) << Collection(res2ColId); 0593 auto job = new CollectionFetchJob(req, this); 0594 AKVERIFYEXEC(job); 0595 0596 Collection::List res; 0597 res = job->collections(); 0598 compareLists(res, req); 0599 } 0600 0601 void CollectionJobTest::testMultiListInvalid() 0602 { 0603 Collection::List req; 0604 req << Collection(res1ColId) << Collection(1234567) << Collection(res2ColId); 0605 auto job = new CollectionFetchJob(req, this); 0606 QVERIFY(!job->exec()); 0607 // not all available collections are fetched 0608 QVERIFY(job->collections().count() != 2); 0609 0610 job = new CollectionFetchJob(req, this); 0611 job->fetchScope().setIgnoreRetrievalErrors(true); 0612 QVERIFY(!job->exec()); 0613 Collection::List res; 0614 res = job->collections(); 0615 req = Collection::List() << Collection(res1ColId) << Collection(res2ColId); 0616 compareLists(res, req); 0617 } 0618 0619 void CollectionJobTest::testRecursiveMultiList() 0620 { 0621 Akonadi::Collection::List toFetch; 0622 toFetch << Collection(res1ColId); 0623 toFetch << Collection(res2ColId); 0624 auto job = new CollectionFetchJob(toFetch, CollectionFetchJob::Recursive); 0625 QSignalSpy spy(job, &CollectionFetchJob::collectionsReceived); 0626 QVERIFY(spy.isValid()); 0627 AKVERIFYEXEC(job); 0628 0629 Collection::List list = job->collections(); 0630 0631 int count = 0; 0632 for (int i = 0; i < spy.count(); ++i) { 0633 auto l = spy[i][0].value<Akonadi::Collection::List>(); 0634 for (int j = 0; j < l.count(); ++j) { 0635 QVERIFY(list.count() > count + j); 0636 QCOMPARE(list[count + j].id(), l[j].id()); 0637 } 0638 count += l.count(); 0639 } 0640 QCOMPARE(count, list.count()); 0641 0642 // check if everything is there 0643 QCOMPARE(list.count(), 4 + 2); 0644 QVERIFY(findCol(list, QStringLiteral("foo")).isValid()); 0645 QVERIFY(findCol(list, QStringLiteral("bar")).isValid()); 0646 QVERIFY(findCol(list, QStringLiteral("bla")).isValid()); // There are two bla folders, but we only check for one. 0647 QVERIFY(findCol(list, QStringLiteral("foo2")).isValid()); 0648 QVERIFY(findCol(list, QStringLiteral("space folder")).isValid()); 0649 } 0650 0651 void CollectionJobTest::testNonOverlappingRootList() 0652 { 0653 Akonadi::Collection::List toFetch; 0654 toFetch << Collection(res1ColId); 0655 toFetch << Collection(res2ColId); 0656 auto job = new CollectionFetchJob(toFetch, CollectionFetchJob::NonOverlappingRoots); 0657 QSignalSpy spy(job, &CollectionFetchJob::collectionsReceived); 0658 QVERIFY(spy.isValid()); 0659 AKVERIFYEXEC(job); 0660 0661 Collection::List list = job->collections(); 0662 0663 int count = 0; 0664 for (int i = 0; i < spy.count(); ++i) { 0665 auto l = spy[i][0].value<Akonadi::Collection::List>(); 0666 for (int j = 0; j < l.count(); ++j) { 0667 QVERIFY(list.count() > count + j); 0668 QCOMPARE(list[count + j].id(), l[j].id()); 0669 } 0670 count += l.count(); 0671 } 0672 QCOMPARE(count, list.count()); 0673 0674 // check if everything is there 0675 QCOMPARE(list.count(), 2); 0676 QVERIFY(findCol(list, QStringLiteral("res1")).isValid()); 0677 QVERIFY(findCol(list, QStringLiteral("res2")).isValid()); 0678 } 0679 0680 void CollectionJobTest::testRidFetch() 0681 { 0682 Collection col; 0683 col.setRemoteId(QStringLiteral("10")); 0684 0685 auto job = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0686 job->fetchScope().setResource(QStringLiteral("akonadi_knut_resource_0")); 0687 AKVERIFYEXEC(job); 0688 QCOMPARE(job->collections().count(), 1); 0689 col = job->collections().first(); 0690 QVERIFY(col.isValid()); 0691 QCOMPARE(col.remoteId(), QString::fromLatin1("10")); 0692 } 0693 0694 void CollectionJobTest::testRidCreateDelete_data() 0695 { 0696 QTest::addColumn<QString>("remoteId"); 0697 QTest::newRow("ASCII") << QString::fromUtf8("MY REMOTE ID"); 0698 QTest::newRow("LATIN1") << QString::fromUtf8("MY REMÖTE ID"); 0699 QTest::newRow("UTF8") << QString::fromUtf8("MY REMOTE 検索表"); 0700 } 0701 0702 void CollectionJobTest::testRidCreateDelete() 0703 { 0704 QFETCH(QString, remoteId); 0705 Collection collection; 0706 collection.setName(QStringLiteral("rid create")); 0707 collection.parentCollection().setRemoteId(QStringLiteral("8")); 0708 collection.setRemoteId(remoteId); 0709 0710 auto resSel = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_2")); 0711 AKVERIFYEXEC(resSel); 0712 0713 auto createJob = new CollectionCreateJob(collection, this); 0714 AKVERIFYEXEC(createJob); 0715 0716 Collection createdCol = createJob->collection(); 0717 QVERIFY(createdCol.isValid()); 0718 QCOMPARE(createdCol.name(), collection.name()); 0719 0720 auto listJob = new CollectionFetchJob(Collection(res3ColId), CollectionFetchJob::FirstLevel, this); 0721 AKVERIFYEXEC(listJob); 0722 Collection listedCol = findCol(listJob->collections(), collection.name()); 0723 QCOMPARE(listedCol, createdCol); 0724 QCOMPARE(listedCol.name(), collection.name()); 0725 0726 QVERIFY(!collection.isValid()); 0727 auto delJob = new CollectionDeleteJob(collection, this); 0728 AKVERIFYEXEC(delJob); 0729 0730 listJob = new CollectionFetchJob(Collection(res3ColId), CollectionFetchJob::FirstLevel, this); 0731 AKVERIFYEXEC(listJob); 0732 QVERIFY(!findCol(listJob->collections(), collection.name()).isValid()); 0733 } 0734 0735 void CollectionJobTest::testAncestorRetrieval() 0736 { 0737 Collection col; 0738 col.setRemoteId(QStringLiteral("10")); 0739 0740 auto job = new CollectionFetchJob(col, CollectionFetchJob::Base, this); 0741 job->fetchScope().setResource(QStringLiteral("akonadi_knut_resource_0")); 0742 job->fetchScope().setAncestorRetrieval(CollectionFetchScope::All); 0743 AKVERIFYEXEC(job); 0744 QCOMPARE(job->collections().count(), 1); 0745 col = job->collections().first(); 0746 QVERIFY(col.isValid()); 0747 QVERIFY(col.parentCollection().isValid()); 0748 QCOMPARE(col.parentCollection().remoteId(), QStringLiteral("6")); 0749 QCOMPARE(col.parentCollection().parentCollection(), Collection::root()); 0750 0751 auto select = new ResourceSelectJob(QStringLiteral("akonadi_knut_resource_0"), this); 0752 AKVERIFYEXEC(select); 0753 Collection col2(col); 0754 col2.setId(-1); // make it invalid but keep the ancestor chain 0755 job = new CollectionFetchJob(col2, CollectionFetchJob::Base, this); 0756 AKVERIFYEXEC(job); 0757 QCOMPARE(job->collections().count(), 1); 0758 col2 = job->collections().first(); 0759 QVERIFY(col2.isValid()); 0760 QCOMPARE(col, col2); 0761 } 0762 0763 void CollectionJobTest::testAncestorAttributeRetrieval() 0764 { 0765 Akonadi::Collection baseCol; 0766 { 0767 baseCol.setParentCollection(Akonadi::Collection(res1ColId)); 0768 baseCol.setName(QStringLiteral("base")); 0769 baseCol.attribute<TestAttribute>(Collection::AddIfMissing)->data = "new"; 0770 auto create = new Akonadi::CollectionCreateJob(baseCol); 0771 AKVERIFYEXEC(create); 0772 baseCol = create->collection(); 0773 } 0774 { 0775 Akonadi::Collection col; 0776 col.setParentCollection(baseCol); 0777 col.setName(QStringLiteral("enabled")); 0778 auto create = new Akonadi::CollectionCreateJob(col); 0779 AKVERIFYEXEC(create); 0780 0781 auto job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base); 0782 job->fetchScope().setAncestorRetrieval(CollectionFetchScope::All); 0783 job->fetchScope().ancestorFetchScope().setFetchIdOnly(false); 0784 job->fetchScope().ancestorFetchScope().fetchAttribute<TestAttribute>(); 0785 AKVERIFYEXEC(job); 0786 Akonadi::Collection result = job->collections().first(); 0787 QCOMPARE(result.parentCollection().hasAttribute<TestAttribute>(), true); 0788 } 0789 0790 // Cleanup 0791 auto deleteJob = new CollectionDeleteJob(baseCol); 0792 AKVERIFYEXEC(deleteJob); 0793 } 0794 0795 void CollectionJobTest::testListPreference() 0796 { 0797 Akonadi::Collection baseCol; 0798 { 0799 baseCol.setParentCollection(Akonadi::Collection(res1ColId)); 0800 baseCol.setName(QStringLiteral("base")); 0801 auto create = new Akonadi::CollectionCreateJob(baseCol); 0802 AKVERIFYEXEC(create); 0803 baseCol = create->collection(); 0804 } 0805 { 0806 Akonadi::Collection col; 0807 col.setParentCollection(baseCol); 0808 col.setEnabled(true); 0809 col.setName(QStringLiteral("enabled")); 0810 auto create = new Akonadi::CollectionCreateJob(col); 0811 AKVERIFYEXEC(create); 0812 0813 auto job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base); 0814 AKVERIFYEXEC(job); 0815 Akonadi::Collection result = job->collections().first(); 0816 QCOMPARE(result.enabled(), true); 0817 QCOMPARE(result.localListPreference(Collection::ListDisplay), Collection::ListDefault); 0818 QCOMPARE(result.localListPreference(Collection::ListSync), Collection::ListDefault); 0819 QCOMPARE(result.localListPreference(Collection::ListIndex), Collection::ListDefault); 0820 } 0821 { 0822 Akonadi::Collection col; 0823 col.setParentCollection(baseCol); 0824 col.setName(QStringLiteral("disabledPref")); 0825 col.setEnabled(true); 0826 col.setLocalListPreference(Collection::ListDisplay, Collection::ListDisabled); 0827 col.setLocalListPreference(Collection::ListSync, Collection::ListDisabled); 0828 col.setLocalListPreference(Collection::ListIndex, Collection::ListDisabled); 0829 auto create = new Akonadi::CollectionCreateJob(col); 0830 AKVERIFYEXEC(create); 0831 auto job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base); 0832 AKVERIFYEXEC(job); 0833 Akonadi::Collection result = job->collections().first(); 0834 QCOMPARE(result.enabled(), true); 0835 QCOMPARE(result.localListPreference(Collection::ListDisplay), Collection::ListDisabled); 0836 QCOMPARE(result.localListPreference(Collection::ListSync), Collection::ListDisabled); 0837 QCOMPARE(result.localListPreference(Collection::ListIndex), Collection::ListDisabled); 0838 } 0839 { 0840 Akonadi::Collection col; 0841 col.setParentCollection(baseCol); 0842 col.setName(QStringLiteral("enabledPref")); 0843 col.setEnabled(false); 0844 col.setLocalListPreference(Collection::ListDisplay, Collection::ListEnabled); 0845 col.setLocalListPreference(Collection::ListSync, Collection::ListEnabled); 0846 col.setLocalListPreference(Collection::ListIndex, Collection::ListEnabled); 0847 auto create = new Akonadi::CollectionCreateJob(col); 0848 AKVERIFYEXEC(create); 0849 auto job = new CollectionFetchJob(create->collection(), CollectionFetchJob::Base); 0850 AKVERIFYEXEC(job); 0851 Akonadi::Collection result = job->collections().first(); 0852 QCOMPARE(result.enabled(), false); 0853 QCOMPARE(result.localListPreference(Collection::ListDisplay), Collection::ListEnabled); 0854 QCOMPARE(result.localListPreference(Collection::ListSync), Collection::ListEnabled); 0855 QCOMPARE(result.localListPreference(Collection::ListIndex), Collection::ListEnabled); 0856 } 0857 0858 // Check list filter 0859 { 0860 auto job = new CollectionFetchJob(baseCol, CollectionFetchJob::FirstLevel); 0861 job->fetchScope().setListFilter(CollectionFetchScope::Display); 0862 AKVERIFYEXEC(job); 0863 QCOMPARE(job->collections().size(), 2); 0864 } 0865 { 0866 auto job = new CollectionFetchJob(baseCol, CollectionFetchJob::FirstLevel); 0867 job->fetchScope().setListFilter(CollectionFetchScope::Sync); 0868 AKVERIFYEXEC(job); 0869 QCOMPARE(job->collections().size(), 2); 0870 } 0871 { 0872 auto job = new CollectionFetchJob(baseCol, CollectionFetchJob::FirstLevel); 0873 job->fetchScope().setListFilter(CollectionFetchScope::Index); 0874 AKVERIFYEXEC(job); 0875 QCOMPARE(job->collections().size(), 2); 0876 } 0877 { 0878 auto job = new CollectionFetchJob(baseCol, CollectionFetchJob::FirstLevel); 0879 job->fetchScope().setListFilter(CollectionFetchScope::Enabled); 0880 AKVERIFYEXEC(job); 0881 QCOMPARE(job->collections().size(), 2); 0882 } 0883 0884 // Cleanup 0885 auto deleteJob = new CollectionDeleteJob(baseCol); 0886 AKVERIFYEXEC(deleteJob); 0887 } 0888 0889 #include "collectionjobtest.moc" 0890 0891 #include "moc_collectionjobtest.cpp"