File indexing completed on 2025-01-05 04:59:55
0001 /* 0002 * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 0006 0007 #include <testlib/qtest_zanshin.h> 0008 0009 #include "akonadi/akonadicachingstorage.h" 0010 #include "akonadi/akonaditaskqueries.h" 0011 #include "akonadi/akonadiserializer.h" 0012 #include "akonadi/akonadiitemfetchjobinterface.h" 0013 0014 #include "testlib/akonadifakedata.h" 0015 #include "testlib/gencollection.h" 0016 #include "testlib/gentodo.h" 0017 #include "testlib/testhelpers.h" 0018 0019 #include "utils/datetime.h" 0020 0021 using namespace Testlib; 0022 0023 class AkonadiTaskQueriesTest : public QObject 0024 { 0025 Q_OBJECT 0026 private: 0027 Akonadi::StorageInterface::Ptr createCachingStorage(AkonadiFakeData &data, const Akonadi::Cache::Ptr &cache) 0028 { 0029 auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); 0030 return Akonadi::StorageInterface::Ptr(new Akonadi::CachingStorage(cache, storage)); 0031 } 0032 0033 private slots: 0034 void shouldLookInAllReportedForAllTasks() 0035 { 0036 // GIVEN 0037 AkonadiFakeData data; 0038 0039 // Two top level collections 0040 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0041 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 0042 0043 // One task in the first collection 0044 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0045 0046 // Two tasks in the second collection 0047 data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); 0048 data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44"))); 0049 0050 // WHEN 0051 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0052 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0053 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0054 Akonadi::Cache::Ptr())); 0055 auto result = queries->findAll(); 0056 result->data(); 0057 result = queries->findAll(); // Should not cause any problem or wrong data 0058 0059 // THEN 0060 QVERIFY(result->data().isEmpty()); 0061 TestHelpers::waitForEmptyJobQueue(); 0062 0063 QCOMPARE(result->data().size(), 3); 0064 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0065 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 0066 QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); 0067 } 0068 0069 void shouldIgnoreItemsWhichAreNotTasks() 0070 { 0071 // GIVEN 0072 AkonadiFakeData data; 0073 0074 // Two top level collections 0075 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0076 0077 // Two items in the collection 0078 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0079 // One of them is not a task 0080 auto item = Akonadi::Item(43); 0081 item.setPayloadFromData("FooBar"); 0082 item.setParentCollection(Akonadi::Collection(42)); 0083 data.createItem(item); 0084 0085 // WHEN 0086 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0087 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0088 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0089 Akonadi::Cache::Ptr())); 0090 auto result = queries->findAll(); 0091 0092 // THEN 0093 QVERIFY(result->data().isEmpty()); 0094 TestHelpers::waitForEmptyJobQueue(); 0095 0096 QCOMPARE(result->data().size(), 1); 0097 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0098 } 0099 0100 void shouldReactToItemAddsForTasksOnly() 0101 { 0102 // GIVEN 0103 AkonadiFakeData data; 0104 0105 // One empty collection 0106 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0107 0108 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0109 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0110 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0111 Akonadi::Cache::Ptr())); 0112 auto result = queries->findAll(); 0113 TestHelpers::waitForEmptyJobQueue(); 0114 QVERIFY(result->data().isEmpty()); 0115 0116 // WHEN 0117 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0118 auto item = Akonadi::Item(43); 0119 item.setPayloadFromData("FooBar"); 0120 item.setParentCollection(Akonadi::Collection(42)); 0121 data.createItem(item); 0122 0123 // THEN 0124 QCOMPARE(result->data().size(), 1); 0125 QCOMPARE(result->data().first()->title(), QStringLiteral("42")); 0126 } 0127 0128 void shouldReactToItemRemovesForAllTasks() 0129 { 0130 // GIVEN 0131 AkonadiFakeData data; 0132 0133 // One top level collection 0134 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0135 0136 // Three task in the collection 0137 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0138 data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); 0139 data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44"))); 0140 0141 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0142 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0143 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0144 Akonadi::Cache::Ptr())); 0145 auto result = queries->findAll(); 0146 TestHelpers::waitForEmptyJobQueue(); 0147 QCOMPARE(result->data().size(), 3); 0148 0149 // WHEN 0150 data.removeItem(Akonadi::Item(43)); 0151 0152 // THEN 0153 QCOMPARE(result->data().size(), 2); 0154 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0155 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 0156 } 0157 0158 void shouldReactToItemChangesForAllTasks() 0159 { 0160 // GIVEN 0161 AkonadiFakeData data; 0162 0163 // One top level collection 0164 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0165 0166 // Three task in the collection 0167 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0168 data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43"))); 0169 data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44"))); 0170 0171 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0172 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0173 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0174 Akonadi::Cache::Ptr())); 0175 auto result = queries->findAll(); 0176 // Even though the pointer didn't change it's convenient to user if we call 0177 // the replace handlers 0178 bool replaceHandlerCalled = false; 0179 result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { 0180 replaceHandlerCalled = true; 0181 }); 0182 TestHelpers::waitForEmptyJobQueue(); 0183 QCOMPARE(result->data().size(), 3); 0184 0185 // WHEN 0186 data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); 0187 0188 // THEN 0189 QCOMPARE(result->data().size(), 3); 0190 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0191 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43bis")); 0192 QCOMPARE(result->data().at(2)->title(), QStringLiteral("44")); 0193 QVERIFY(replaceHandlerCalled); 0194 } 0195 0196 void shouldLookInAllChildrenReportedForAllChildrenTask() 0197 { 0198 // GIVEN 0199 AkonadiFakeData data; 0200 0201 // One top level collection 0202 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0203 0204 // Three tasks in the collection (two being children of the first one) 0205 data.createItem(GenTodo().withId(42).withParent(42) 0206 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0207 data.createItem(GenTodo().withId(43).withParent(42) 0208 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0209 .withParentUid(QStringLiteral("uid-42"))); 0210 data.createItem(GenTodo().withId(44).withParent(42) 0211 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0212 .withParentUid(QStringLiteral("uid-42"))); 0213 0214 // WHEN 0215 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0216 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0217 serializer, 0218 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0219 Akonadi::Cache::Ptr())); 0220 auto task = serializer->createTaskFromItem(data.item(42)); 0221 auto result = queries->findChildren(task); 0222 result->data(); 0223 result = queries->findChildren(task); // Should not cause any problem or wrong data 0224 0225 // THEN 0226 QVERIFY(result->data().isEmpty()); 0227 TestHelpers::waitForEmptyJobQueue(); 0228 0229 QCOMPARE(result->data().size(), 2); 0230 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 0231 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 0232 0233 // Should not change nothing 0234 result = queries->findChildren(task); 0235 0236 QCOMPARE(result->data().size(), 2); 0237 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 0238 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 0239 } 0240 0241 void shouldNotCrashWhenWeAskAgainTheSameChildrenList() 0242 { 0243 // GIVEN 0244 AkonadiFakeData data; 0245 0246 // One top level collection 0247 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0248 0249 // One task in the collection 0250 data.createItem(GenTodo().withId(42).withParent(42) 0251 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0252 0253 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0254 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0255 serializer, 0256 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0257 Akonadi::Cache::Ptr())); 0258 auto task = serializer->createTaskFromItem(data.item(42)); 0259 0260 // The bug we're trying to hit here is the following: 0261 // - when findChildren is called the first time a provider is created internally 0262 // - result is deleted at the end of the loop, no one holds the provider with 0263 // a strong reference anymore so it is deleted as well 0264 // - when findChildren is called the second time, there's a risk of a dangling 0265 // pointer if the recycling of providers is wrongly implemented which can lead 0266 // to a crash, if it is properly done no crash will occur 0267 for (int i = 0; i < 2; i++) { 0268 // WHEN * 2 0269 auto result = queries->findChildren(task); 0270 0271 // THEN * 2 0272 QVERIFY(result->data().isEmpty()); 0273 TestHelpers::waitForEmptyJobQueue(); 0274 QVERIFY(result->data().isEmpty()); 0275 } 0276 } 0277 0278 void shouldReactToItemAddsForChildrenTask() 0279 { 0280 // GIVEN 0281 AkonadiFakeData data; 0282 0283 // One top level collections 0284 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0285 0286 // One task in the collection 0287 data.createItem(GenTodo().withId(42).withParent(42) 0288 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0289 0290 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0291 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0292 serializer, 0293 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0294 Akonadi::Cache::Ptr())); 0295 auto task = serializer->createTaskFromItem(data.item(42)); 0296 auto result = queries->findChildren(task); 0297 TestHelpers::waitForEmptyJobQueue(); 0298 QVERIFY(result->data().isEmpty()); 0299 0300 // WHEN 0301 data.createItem(GenTodo().withId(43).withParent(42) 0302 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0303 .withParentUid(QStringLiteral("uid-42"))); 0304 data.createItem(GenTodo().withId(44).withParent(42) 0305 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0306 .withParentUid(QStringLiteral("uid-42"))); 0307 0308 // THEN 0309 QCOMPARE(result->data().size(), 2); 0310 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 0311 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 0312 } 0313 0314 void shouldReactToItemChangesForChildrenTask() 0315 { 0316 // GIVEN 0317 AkonadiFakeData data; 0318 0319 // One top level collection 0320 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0321 0322 // Three tasks in the collection (two being children of the first one) 0323 data.createItem(GenTodo().withId(42).withParent(42) 0324 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0325 data.createItem(GenTodo().withId(43).withParent(42) 0326 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0327 .withParentUid(QStringLiteral("uid-42"))); 0328 data.createItem(GenTodo().withId(44).withParent(42) 0329 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0330 .withParentUid(QStringLiteral("uid-42"))); 0331 0332 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0333 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0334 serializer, 0335 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0336 Akonadi::Cache::Ptr())); 0337 auto task = serializer->createTaskFromItem(data.item(42)); 0338 auto result = queries->findChildren(task); 0339 0340 bool replaceHandlerCalled = false; 0341 result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { 0342 replaceHandlerCalled = true; 0343 }); 0344 TestHelpers::waitForEmptyJobQueue(); 0345 QCOMPARE(result->data().size(), 2); 0346 0347 // WHEN 0348 data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); 0349 0350 // THEN 0351 QCOMPARE(result->data().size(), 2); 0352 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43bis")); 0353 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 0354 0355 QVERIFY(replaceHandlerCalled); 0356 } 0357 0358 void shouldRemoveItemFromCorrespondingResultWhenRelatedItemChangeForChildrenTask() 0359 { 0360 // GIVEN 0361 AkonadiFakeData data; 0362 0363 // One top level collection 0364 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0365 0366 // Three tasks in the collection (two being children of the first one) 0367 data.createItem(GenTodo().withId(42).withParent(42) 0368 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0369 data.createItem(GenTodo().withId(43).withParent(42) 0370 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0371 .withParentUid(QStringLiteral("uid-42"))); 0372 data.createItem(GenTodo().withId(44).withParent(42) 0373 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0374 .withParentUid(QStringLiteral("uid-42"))); 0375 0376 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0377 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0378 serializer, 0379 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0380 Akonadi::Cache::Ptr())); 0381 auto task = serializer->createTaskFromItem(data.item(42)); 0382 auto result = queries->findChildren(task); 0383 TestHelpers::waitForEmptyJobQueue(); 0384 QCOMPARE(result->data().size(), 2); 0385 0386 // WHEN 0387 data.modifyItem(GenTodo(data.item(43)).withParentUid(QLatin1StringView(""))); 0388 0389 // THEN 0390 QCOMPARE(result->data().size(), 1); 0391 QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); 0392 } 0393 0394 void shouldAddItemToCorrespondingResultWhenRelatedItemChangeForChildrenTask() 0395 { 0396 // GIVEN 0397 AkonadiFakeData data; 0398 0399 // One top level collection 0400 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0401 0402 // Three tasks in the collection (two being top level) 0403 data.createItem(GenTodo().withId(42).withParent(42) 0404 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0405 data.createItem(GenTodo().withId(43).withParent(42) 0406 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0407 data.createItem(GenTodo().withId(44).withParent(42) 0408 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0409 .withParentUid(QStringLiteral("uid-42"))); 0410 0411 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0412 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0413 serializer, 0414 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0415 Akonadi::Cache::Ptr())); 0416 auto task = serializer->createTaskFromItem(data.item(42)); 0417 auto result = queries->findChildren(task); 0418 0419 bool replaceHandlerCalled = false; 0420 result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { 0421 replaceHandlerCalled = true; 0422 }); 0423 TestHelpers::waitForEmptyJobQueue(); 0424 QCOMPARE(result->data().size(), 1); 0425 0426 // WHEN 0427 data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42"))); 0428 0429 // THEN 0430 QCOMPARE(result->data().size(), 2); 0431 QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); 0432 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 0433 0434 QVERIFY(!replaceHandlerCalled); 0435 } 0436 0437 void shouldMoveItemToCorrespondingResultWhenRelatedItemChangeForChildTask() 0438 { 0439 // GIVEN 0440 AkonadiFakeData data; 0441 0442 // One top level collection 0443 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0444 0445 // Three tasks in the collection (two being top level) 0446 data.createItem(GenTodo().withId(42).withParent(42) 0447 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0448 data.createItem(GenTodo().withId(43).withParent(42) 0449 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0450 data.createItem(GenTodo().withId(44).withParent(42) 0451 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0452 .withParentUid(QStringLiteral("uid-42"))); 0453 0454 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0455 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0456 serializer, 0457 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0458 Akonadi::Cache::Ptr())); 0459 auto task1 = serializer->createTaskFromItem(data.item(42)); 0460 auto task2 = serializer->createTaskFromItem(data.item(43)); 0461 auto result1 = queries->findChildren(task1); 0462 auto result2 = queries->findChildren(task2); 0463 0464 TestHelpers::waitForEmptyJobQueue(); 0465 QCOMPARE(result1->data().size(), 1); 0466 QCOMPARE(result1->data().at(0)->title(), QStringLiteral("44")); 0467 QCOMPARE(result2->data().size(), 0); 0468 0469 // WHEN 0470 data.modifyItem(GenTodo(data.item(44)).withParentUid(QStringLiteral("uid-43"))); 0471 0472 // THEN 0473 QCOMPARE(result1->data().size(), 0); 0474 QCOMPARE(result2->data().size(), 1); 0475 QCOMPARE(result2->data().at(0)->title(), QStringLiteral("44")); 0476 } 0477 0478 void shouldReactToItemRemovesForChildrenTask() 0479 { 0480 // GIVEN 0481 AkonadiFakeData data; 0482 0483 // One top level collection 0484 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0485 0486 // Three tasks in the collection (two being children of the first one) 0487 data.createItem(GenTodo().withId(42).withParent(42) 0488 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0489 data.createItem(GenTodo().withId(43).withParent(42) 0490 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0491 .withParentUid(QStringLiteral("uid-42"))); 0492 data.createItem(GenTodo().withId(44).withParent(42) 0493 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0494 .withParentUid(QStringLiteral("uid-42"))); 0495 0496 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0497 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0498 serializer, 0499 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0500 Akonadi::Cache::Ptr())); 0501 auto task = serializer->createTaskFromItem(data.item(42)); 0502 auto result = queries->findChildren(task); 0503 TestHelpers::waitForEmptyJobQueue(); 0504 QCOMPARE(result->data().size(), 2); 0505 0506 // WHEN 0507 data.removeItem(Akonadi::Item(43)); 0508 0509 // THEN 0510 QCOMPARE(result->data().size(), 1); 0511 QCOMPARE(result->data().at(0)->title(), QStringLiteral("44")); 0512 } 0513 0514 void shouldLookInAllReportedForTopLevelTasks() 0515 { 0516 // GIVEN 0517 AkonadiFakeData data; 0518 0519 // Two top level collections 0520 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0521 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 0522 0523 // One task in the first collection 0524 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0525 0526 // Two toplevel tasks in the second collection, one with a child 0527 data.createItem(GenTodo().withId(43).withUid("parent-43").withParent(43).withTitle(QStringLiteral("43"))); 0528 data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44")).withParentUid(QStringLiteral("2"))); // non-existing parent 0529 data.createItem(GenTodo().withId(45).withParent(43).withTitle(QStringLiteral("45")).withParentUid(QStringLiteral("parent-43"))); // existing parent 0530 0531 // WHEN 0532 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0533 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0534 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0535 Akonadi::Cache::Ptr())); 0536 auto result = queries->findInboxTopLevel(); 0537 result->data(); 0538 result = queries->findInboxTopLevel(); // Should not cause any problem or wrong data 0539 0540 // THEN 0541 QVERIFY(result->data().isEmpty()); 0542 TestHelpers::waitForEmptyJobQueue(); 0543 0544 QCOMPARE(result->data().size(), 2); 0545 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0546 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 0547 } 0548 0549 void shouldReactToItemAddsForTopLevelTasks() 0550 { 0551 // GIVEN 0552 AkonadiFakeData data; 0553 0554 // One top level collection 0555 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0556 0557 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0558 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0559 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0560 Akonadi::Cache::Ptr())); 0561 auto result = queries->findInboxTopLevel(); 0562 TestHelpers::waitForEmptyJobQueue(); 0563 QVERIFY(result->data().isEmpty()); 0564 0565 // WHEN 0566 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 0567 data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).withParentUid(QStringLiteral("2"))); 0568 0569 // THEN 0570 QCOMPARE(result->data().size(), 1); 0571 QCOMPARE(result->data().first()->title(), QStringLiteral("42")); 0572 } 0573 0574 void shouldReactToItemRemovesForTopLevelTasks() 0575 { 0576 // GIVEN 0577 AkonadiFakeData data; 0578 0579 // One top level collection 0580 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0581 0582 // Three tasks in the collection (one being child of the second one) 0583 data.createItem(GenTodo().withId(42).withParent(42) 0584 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0585 data.createItem(GenTodo().withId(43).withParent(42) 0586 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0587 data.createItem(GenTodo().withId(44).withParent(42) 0588 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0589 .withParentUid(QStringLiteral("uid-43"))); 0590 0591 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0592 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0593 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0594 Akonadi::Cache::Ptr())); 0595 auto result = queries->findInboxTopLevel(); 0596 TestHelpers::waitForEmptyJobQueue(); 0597 QCOMPARE(result->data().size(), 2); 0598 0599 // WHEN 0600 data.removeItem(Akonadi::Item(43)); 0601 0602 // THEN 0603 QCOMPARE(result->data().size(), 1); 0604 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0605 } 0606 0607 void shouldReactToItemChangesForTopLevelTasks() 0608 { 0609 // GIVEN 0610 AkonadiFakeData data; 0611 0612 // One top level collection 0613 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0614 0615 // Three tasks in the collection (one being child of the second one) 0616 data.createItem(GenTodo().withId(42).withParent(42) 0617 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0618 data.createItem(GenTodo().withId(43).withParent(42) 0619 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0620 data.createItem(GenTodo().withId(44).withParent(42) 0621 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0622 .withParentUid(QStringLiteral("uid-43"))); 0623 0624 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0625 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0626 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0627 Akonadi::Cache::Ptr())); 0628 auto result = queries->findInboxTopLevel(); 0629 // Even though the pointer didn't change it's convenient to user if we call 0630 // the replace handlers 0631 bool replaceHandlerCalled = false; 0632 result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) { 0633 replaceHandlerCalled = true; 0634 }); 0635 TestHelpers::waitForEmptyJobQueue(); 0636 QCOMPARE(result->data().size(), 2); 0637 0638 // WHEN 0639 data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis"))); 0640 0641 // THEN 0642 QCOMPARE(result->data().size(), 2); 0643 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0644 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43bis")); 0645 QVERIFY(replaceHandlerCalled); 0646 } 0647 0648 void shouldRemoveItemFromTopLevelResultWhenRelatedItemChangeForTopLevelTask() 0649 { 0650 // GIVEN 0651 AkonadiFakeData data; 0652 0653 // One top level collection 0654 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0655 0656 // Three tasks in the collection (one being child of the second one) 0657 data.createItem(GenTodo().withId(42).withParent(42) 0658 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0659 data.createItem(GenTodo().withId(43).withParent(42) 0660 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0661 data.createItem(GenTodo().withId(44).withParent(42) 0662 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0663 .withParentUid(QStringLiteral("uid-43"))); 0664 0665 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0666 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0667 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0668 Akonadi::Cache::Ptr())); 0669 auto result = queries->findInboxTopLevel(); 0670 TestHelpers::waitForEmptyJobQueue(); 0671 QCOMPARE(result->data().size(), 2); 0672 0673 // WHEN 0674 data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42"))); 0675 0676 // THEN 0677 QCOMPARE(result->data().size(), 1); 0678 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0679 } 0680 0681 void shouldAddItemToTopLevelResultWhenRelatedItemChangeForChildrenTask() 0682 { 0683 // GIVEN 0684 AkonadiFakeData data; 0685 0686 // One top level collection 0687 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0688 0689 // Three tasks in the collection (one being child of the second one) 0690 data.createItem(GenTodo().withId(42).withParent(42) 0691 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0692 data.createItem(GenTodo().withId(43).withParent(42) 0693 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 0694 .withParentUid(QStringLiteral("uid-42"))); 0695 data.createItem(GenTodo().withId(44).withParent(42) 0696 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0697 .withParentUid(QStringLiteral("uid-43"))); 0698 0699 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0700 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0701 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0702 Akonadi::Cache::Ptr())); 0703 auto result = queries->findInboxTopLevel(); 0704 TestHelpers::waitForEmptyJobQueue(); 0705 QCOMPARE(result->data().size(), 1); 0706 0707 // WHEN 0708 data.modifyItem(GenTodo(data.item(43)).withParentUid(QString())); 0709 0710 // THEN 0711 QCOMPARE(result->data().size(), 2); 0712 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 0713 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 0714 } 0715 0716 void shouldRemoveParentNodeAndMoveChildrenInTopLevelResult() 0717 { 0718 // GIVEN 0719 AkonadiFakeData data; 0720 0721 // One top level collection 0722 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0723 0724 // Three tasks in the collection (one being child of the second one) 0725 data.createItem(GenTodo().withId(42).withParent(42) 0726 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0727 data.createItem(GenTodo().withId(43).withParent(42) 0728 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0729 data.createItem(GenTodo().withId(44).withParent(42) 0730 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0731 .withParentUid(QStringLiteral("uid-43"))); 0732 0733 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0734 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 0735 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0736 Akonadi::Cache::Ptr())); 0737 auto result = queries->findInboxTopLevel(); 0738 TestHelpers::waitForEmptyJobQueue(); 0739 QCOMPARE(result->data().size(), 2); 0740 0741 auto resultChild = queries->findChildren(result->data().at(1)); 0742 TestHelpers::waitForEmptyJobQueue(); 0743 QCOMPARE(resultChild->data().size(), 1); 0744 0745 // WHEN 0746 data.removeItem(Akonadi::Item(43)); 0747 0748 // THEN 0749 QCOMPARE(resultChild->data().size(), 0); 0750 QCOMPARE(result->data().size(), 1); // FIXME: Should become 2 once we got a proper cache in place 0751 } 0752 0753 void shouldNotCrashDuringFindChildrenWhenJobIsKilled() 0754 { 0755 // GIVEN 0756 AkonadiFakeData data; 0757 0758 // One top level collection 0759 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0760 0761 // Three tasks in the collection (two being children of the first one) 0762 data.createItem(GenTodo().withId(42).withParent(42) 0763 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0764 data.createItem(GenTodo().withId(43).withParent(42) 0765 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0766 data.createItem(GenTodo().withId(44).withParent(42) 0767 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0768 .withParentUid(QStringLiteral("uid-42"))); 0769 0770 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0771 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 0772 serializer, 0773 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 0774 Akonadi::Cache::Ptr())); 0775 0776 data.storageBehavior().setFetchItemErrorCode(42, KJob::KilledJobError); 0777 0778 // WHEN 0779 auto task1 = serializer->createTaskFromItem(data.item(42)); 0780 auto result = queries->findChildren(task1); 0781 0782 // THEN 0783 QVERIFY(result->data().isEmpty()); 0784 TestHelpers::waitForEmptyJobQueue(); 0785 QVERIFY(result->data().isEmpty()); 0786 } 0787 0788 0789 void shouldNotCrashDuringFindChildrenWhenItemsJobReceiveResult_data() 0790 { 0791 QTest::addColumn<int>("errorCode"); 0792 QTest::addColumn<int>("fetchBehavior"); 0793 QTest::addColumn<bool>("deleteQuery"); 0794 0795 QTest::newRow("No error with empty list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << false; 0796 QTest::newRow("Error with empty list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) << true; 0797 QTest::newRow("Error with list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) << true; 0798 } 0799 0800 void shouldNotCrashDuringFindChildrenWhenItemsJobReceiveResult() 0801 { 0802 // GIVEN 0803 AkonadiFakeData data; 0804 0805 // One top level collection 0806 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0807 0808 // Three tasks in the collection (two being children of the first one) 0809 data.createItem(GenTodo().withId(42).withParent(42) 0810 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0811 data.createItem(GenTodo().withId(43).withParent(42) 0812 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0813 data.createItem(GenTodo().withId(44).withParent(42) 0814 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0815 .withParentUid(QStringLiteral("uid-42"))); 0816 0817 auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); 0818 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0819 auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); 0820 std::unique_ptr<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 0821 serializer, 0822 monitor, 0823 Akonadi::Cache::Ptr())); 0824 0825 QFETCH(int, errorCode); 0826 QFETCH(int, fetchBehavior); 0827 QFETCH(bool, deleteQuery); 0828 0829 data.storageBehavior().setFetchItemsErrorCode(42, errorCode); 0830 data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(fetchBehavior)); 0831 0832 // WHEN 0833 auto task1 = serializer->createTaskFromItem(data.item(42)); 0834 auto result = queries->findChildren(task1); 0835 0836 if (deleteQuery) 0837 delete queries.release(); 0838 0839 // THEN 0840 QVERIFY(result->data().isEmpty()); 0841 TestHelpers::waitForEmptyJobQueue(); 0842 QVERIFY(result->data().isEmpty()); 0843 } 0844 0845 void shouldNotCrashDuringFindAllWhenFetchJobFailedOrEmpty_data() 0846 { 0847 QTest::addColumn<int>("colErrorCode"); 0848 QTest::addColumn<int>("colFetchBehavior"); 0849 QTest::addColumn<int>("itemsErrorCode"); 0850 QTest::addColumn<int>("itemsFetchBehavior"); 0851 QTest::addColumn<bool>("deleteQuery"); 0852 0853 QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0854 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0855 << false; 0856 0857 QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0858 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0859 << true; 0860 0861 QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0862 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0863 << true; 0864 0865 QTest::newRow("No error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0866 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0867 << false; 0868 0869 QTest::newRow("Error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0870 << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0871 << false; 0872 0873 QTest::newRow("Error with item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0874 << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0875 << false; 0876 } 0877 0878 void shouldNotCrashDuringFindAllWhenFetchJobFailedOrEmpty() 0879 { 0880 // GIVEN 0881 AkonadiFakeData data; 0882 0883 // One top level collection 0884 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0885 0886 // Three tasks in the collection 0887 data.createItem(GenTodo().withId(42).withParent(42) 0888 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0889 data.createItem(GenTodo().withId(43).withParent(42) 0890 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0891 data.createItem(GenTodo().withId(44).withParent(42) 0892 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); 0893 0894 auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); 0895 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0896 auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); 0897 std::unique_ptr<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 0898 serializer, 0899 monitor, 0900 Akonadi::Cache::Ptr())); 0901 0902 QFETCH(int, colErrorCode); 0903 QFETCH(int, colFetchBehavior); 0904 data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); 0905 data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), 0906 AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); 0907 0908 QFETCH(int, itemsErrorCode); 0909 QFETCH(int, itemsFetchBehavior); 0910 data.storageBehavior().setFetchItemsErrorCode(42, itemsErrorCode); 0911 data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(itemsFetchBehavior)); 0912 0913 QFETCH(bool, deleteQuery); 0914 0915 0916 // WHEN 0917 auto result = queries->findAll(); 0918 0919 if (deleteQuery) 0920 delete queries.release(); 0921 0922 // THEN 0923 QVERIFY(result->data().isEmpty()); 0924 TestHelpers::waitForEmptyJobQueue(); 0925 QVERIFY(result->data().isEmpty()); 0926 } 0927 0928 void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty_data() 0929 { 0930 QTest::addColumn<int>("colErrorCode"); 0931 QTest::addColumn<int>("colFetchBehavior"); 0932 QTest::addColumn<int>("itemsErrorCode"); 0933 QTest::addColumn<int>("itemsFetchBehavior"); 0934 QTest::addColumn<bool>("deleteQuery"); 0935 0936 QTest::newRow("No error with empty collection list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0937 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0938 << false; 0939 0940 QTest::newRow("Error with empty collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0941 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0942 << true; 0943 0944 QTest::newRow("Error with collection list") << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0945 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0946 << true; 0947 0948 QTest::newRow("No error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0949 << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0950 << false; 0951 0952 QTest::newRow("Error with empty item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0953 << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::EmptyFetch) 0954 << false; 0955 0956 QTest::newRow("Error with item list") << int(KJob::NoError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0957 << int(KJob::KilledJobError) << int(AkonadiFakeStorageBehavior::NormalFetch) 0958 << false; 0959 } 0960 0961 void shouldNotCrashDuringFindTopLevelWhenFetchJobFailedOrEmpty() 0962 { 0963 // GIVEN 0964 AkonadiFakeData data; 0965 0966 // One top level collection 0967 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 0968 0969 // Three tasks in the collection (third one being child of the first one) 0970 data.createItem(GenTodo().withId(42).withParent(42) 0971 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 0972 data.createItem(GenTodo().withId(43).withParent(42) 0973 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 0974 data.createItem(GenTodo().withId(44).withParent(42) 0975 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 0976 .withParentUid(QStringLiteral("uid-42"))); 0977 0978 auto storage = Akonadi::StorageInterface::Ptr(data.createStorage()); 0979 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 0980 auto monitor = Akonadi::MonitorInterface::Ptr(data.createMonitor()); 0981 std::unique_ptr<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 0982 serializer, 0983 monitor, 0984 Akonadi::Cache::Ptr())); 0985 0986 QFETCH(int, colErrorCode); 0987 QFETCH(int, colFetchBehavior); 0988 data.storageBehavior().setFetchCollectionsErrorCode(Akonadi::Collection::root().id(), colErrorCode); 0989 data.storageBehavior().setFetchCollectionsBehavior(Akonadi::Collection::root().id(), 0990 AkonadiFakeStorageBehavior::FetchBehavior(colFetchBehavior)); 0991 0992 QFETCH(int, itemsErrorCode); 0993 QFETCH(int, itemsFetchBehavior); 0994 data.storageBehavior().setFetchItemsErrorCode(42, itemsErrorCode); 0995 data.storageBehavior().setFetchItemsBehavior(42, AkonadiFakeStorageBehavior::FetchBehavior(itemsFetchBehavior)); 0996 0997 QFETCH(bool, deleteQuery); 0998 0999 1000 // WHEN 1001 auto result = queries->findInboxTopLevel(); 1002 1003 if (deleteQuery) 1004 delete queries.release(); 1005 1006 // THEN 1007 QVERIFY(result->data().isEmpty()); 1008 TestHelpers::waitForEmptyJobQueue(); 1009 QVERIFY(result->data().isEmpty()); 1010 } 1011 1012 void shouldIgnoreProjectsWhenReportingTopLevelTasks() 1013 { 1014 // GIVEN 1015 AkonadiFakeData data; 1016 1017 // Two top level collections 1018 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1019 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1020 1021 // One task in the first collection 1022 data.createItem(GenTodo().withId(42).withParent(42) 1023 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 1024 1025 // Two tasks and one project in the second collection 1026 data.createItem(GenTodo().withId(43).withParent(43) 1027 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 1028 data.createItem(GenTodo().withId(44).withParent(43) 1029 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 1030 .withParentUid(QStringLiteral("uid-43"))); 1031 data.createItem(GenTodo().withId(45).withParent(43) 1032 .withTitle(QStringLiteral("45")).withUid(QStringLiteral("uid-45")) 1033 .asProject()); 1034 1035 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1036 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1037 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1038 Akonadi::Cache::Ptr())); 1039 auto result = queries->findInboxTopLevel(); 1040 result->data(); 1041 result = queries->findInboxTopLevel(); // Should not cause any problem or wrong data 1042 1043 // THEN 1044 QVERIFY(result->data().isEmpty()); 1045 TestHelpers::waitForEmptyJobQueue(); 1046 1047 QCOMPARE(result->data().size(), 2); 1048 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1049 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 1050 } 1051 1052 void shouldLookInAllSelectedCollectionsForInboxTopLevel() 1053 { 1054 // GIVEN 1055 AkonadiFakeData data; 1056 1057 // Three top level collections 1058 data.createCollection(GenCollection().withId(42).withRootAsParent().withNoteContent()); 1059 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1060 data.createCollection(GenCollection().withId(44).withRootAsParent().withTaskContent().selected(false)); 1061 1062 // Two tasks in the second collection 1063 data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); 1064 data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44"))); 1065 1066 // One task in the third collection 1067 data.createItem(GenTodo().withId(45).withParent(44).withTitle(QStringLiteral("45"))); 1068 1069 // WHEN 1070 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1071 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1072 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1073 Akonadi::Cache::Ptr())); 1074 auto result = queries->findInboxTopLevel(); 1075 result->data(); 1076 result = queries->findInboxTopLevel(); // Should not cause any problem or wrong data 1077 1078 // THEN 1079 QVERIFY(result->data().isEmpty()); 1080 TestHelpers::waitForEmptyJobQueue(); 1081 1082 QCOMPARE(result->data().size(), 2); 1083 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 1084 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 1085 } 1086 1087 void shouldIgnoreItemsWhichAreNotTasksInInboxTopLevel() 1088 { 1089 // GIVEN 1090 AkonadiFakeData data; 1091 1092 // One top level collection 1093 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1094 1095 // Two items in the collection 1096 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 1097 // One of them is not a task 1098 auto item = Akonadi::Item(43); 1099 item.setPayloadFromData("FooBar"); 1100 item.setParentCollection(Akonadi::Collection(42)); 1101 data.createItem(item); 1102 1103 // WHEN 1104 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1105 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1106 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1107 Akonadi::Cache::Ptr())); 1108 auto result = queries->findInboxTopLevel(); 1109 1110 // THEN 1111 QVERIFY(result->data().isEmpty()); 1112 TestHelpers::waitForEmptyJobQueue(); 1113 1114 QCOMPARE(result->data().size(), 1); 1115 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1116 } 1117 1118 void shouldNotHaveTasksWithParentsInInboxTopLevel() 1119 { 1120 // TODO: Note that this specification is kind of an over simplification which 1121 // assumes that all the underlying data is correct. Ideally it should be checked 1122 // that the uid referred to actually points to a todo which exists in a proper 1123 // collection. We will need a cache to be able to implement that properly though. 1124 1125 // GIVEN 1126 AkonadiFakeData data; 1127 1128 // One top level collection 1129 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1130 1131 // Three items in the collection 1132 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 1133 data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")).withParentUid(QStringLiteral("uid-42"))); 1134 data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")).withParentUid(QStringLiteral("foo"))); 1135 1136 // WHEN 1137 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1138 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1139 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1140 Akonadi::Cache::Ptr())); 1141 auto result = queries->findInboxTopLevel(); 1142 1143 // THEN 1144 QVERIFY(result->data().isEmpty()); 1145 TestHelpers::waitForEmptyJobQueue(); 1146 1147 QCOMPARE(result->data().size(), 1); 1148 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1149 } 1150 1151 void shouldHaveTasksWithContextsInInboxTopLevel_data() 1152 { 1153 QTest::addColumn<bool>("hasContexts"); 1154 QTest::addColumn<bool>("isExpectedInInbox"); 1155 1156 QTest::newRow("task with no context") << false << true; 1157 QTest::newRow("task with contexts") << true << true; 1158 } 1159 1160 void shouldHaveTasksWithContextsInInboxTopLevel() 1161 { 1162 // GIVEN 1163 AkonadiFakeData data; 1164 1165 // One top level collection 1166 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1167 1168 // One context item 1169 data.createItem(GenTodo().withParent(42).withId(1).withUid("ctx-42").withTitle(QStringLiteral("Context 42")).asContext()); 1170 1171 // One item in the collection 1172 QFETCH(bool, hasContexts); 1173 auto contextUids = QStringList(); 1174 if (hasContexts) contextUids << "ctx-42"; 1175 1176 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withContexts(contextUids)); 1177 1178 // WHEN 1179 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1180 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1181 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1182 Akonadi::Cache::Ptr())); 1183 auto result = queries->findInboxTopLevel(); 1184 1185 // THEN 1186 QVERIFY(result->data().isEmpty()); 1187 TestHelpers::waitForEmptyJobQueue(); 1188 1189 QFETCH(bool, isExpectedInInbox); 1190 if (isExpectedInInbox) { 1191 QCOMPARE(result->data().size(), 1); 1192 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1193 } else { 1194 QVERIFY(result->data().isEmpty()); 1195 } 1196 } 1197 1198 void shouldReactToItemAddsForInboxTopLevel_data() 1199 { 1200 QTest::addColumn<bool>("reactionExpected"); 1201 QTest::addColumn<QString>("relatedUid"); 1202 QTest::addColumn<bool>("hasContexts"); 1203 1204 QTest::newRow("task which should be in inbox") << true << QString() << false; 1205 QTest::newRow("task with related uid") << false << "foo" << false; 1206 QTest::newRow("task with context") << true << QString() << true; 1207 } 1208 1209 void shouldReactToItemAddsForInboxTopLevel() 1210 { 1211 // GIVEN 1212 AkonadiFakeData data; 1213 1214 // One top level collection 1215 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1216 1217 // One context item 1218 data.createItem(GenTodo().withParent(42).withId(1).withUid("ctx-42").withTitle(QStringLiteral("Context 1")).asContext()); 1219 1220 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1221 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1222 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1223 Akonadi::Cache::Ptr())); 1224 auto result = queries->findInboxTopLevel(); 1225 TestHelpers::waitForEmptyJobQueue(); 1226 QVERIFY(result->data().isEmpty()); 1227 1228 // WHEN 1229 QFETCH(QString, relatedUid); 1230 QFETCH(bool, hasContexts); 1231 auto contextUids = QStringList(); 1232 if (hasContexts) contextUids << "ctx-42"; 1233 1234 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withContexts(contextUids).withParentUid(relatedUid)); 1235 1236 // THEN 1237 QFETCH(bool, reactionExpected); 1238 if (reactionExpected) { 1239 QCOMPARE(result->data().size(), 1); 1240 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1241 } else { 1242 QVERIFY(result->data().isEmpty()); 1243 } 1244 } 1245 1246 void shouldReactToItemRemovesForInboxTopLevel() 1247 { 1248 // GIVEN 1249 AkonadiFakeData data; 1250 1251 // One top level collection 1252 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1253 1254 // One item in the collection 1255 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 1256 1257 // WHEN 1258 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1259 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1260 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1261 Akonadi::Cache::Ptr())); 1262 auto result = queries->findInboxTopLevel(); 1263 TestHelpers::waitForEmptyJobQueue(); 1264 QCOMPARE(result->data().size(), 1); 1265 QCOMPARE(result->data().first()->title(), QStringLiteral("42")); 1266 1267 // WHEN 1268 data.removeItem(Akonadi::Item(42)); 1269 1270 // THEN 1271 QVERIFY(result->data().isEmpty()); 1272 } 1273 1274 void shouldReactToItemChangesForInboxTopLevel_data() 1275 { 1276 QTest::addColumn<bool>("inListAfterChange"); 1277 QTest::addColumn<QString>("relatedUidBefore"); 1278 QTest::addColumn<QString>("relatedUidAfter"); 1279 1280 QTest::newRow("task appears in inbox (related uid)") << true << "foo" << QString(); 1281 QTest::newRow("task disappears from inbox (related uid)") << false << QString() << "foo"; 1282 } 1283 1284 void shouldReactToItemChangesForInboxTopLevel() 1285 { 1286 // GIVEN 1287 AkonadiFakeData data; 1288 1289 // One top level collection 1290 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1291 1292 // One context item 1293 data.createItem(GenTodo().withParent(42).withId(1).withUid("ctx-42").withTitle(QStringLiteral("Context 1")).asContext()); 1294 1295 // Task data 1296 QFETCH(QString, relatedUidBefore); 1297 1298 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).withParentUid(relatedUidBefore)); 1299 1300 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1301 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1302 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1303 Akonadi::Cache::Ptr())); 1304 auto result = queries->findInboxTopLevel(); 1305 TestHelpers::waitForEmptyJobQueue(); 1306 1307 QFETCH(bool, inListAfterChange); 1308 1309 if (inListAfterChange) { 1310 QVERIFY(result->data().isEmpty()); 1311 } else { 1312 QCOMPARE(result->data().size(), 1); 1313 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1314 } 1315 1316 // WHEN 1317 QFETCH(QString, relatedUidAfter); 1318 1319 data.modifyItem(GenTodo(data.item(42)).withParentUid(relatedUidAfter)); 1320 1321 // THEN 1322 if (inListAfterChange) { 1323 QCOMPARE(result->data().size(), 1); 1324 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1325 } else { 1326 QVERIFY(result->data().isEmpty()); 1327 } 1328 } 1329 1330 void shouldReactToCollectionSelectionChangesForInboxTopLevel() 1331 { 1332 // GIVEN 1333 AkonadiFakeData data; 1334 1335 // Two top level collections 1336 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1337 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1338 1339 // One task in each collection 1340 data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42"))); 1341 data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43"))); 1342 1343 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(Akonadi::StorageInterface::Ptr(data.createStorage()), 1344 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1345 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1346 Akonadi::Cache::Ptr())); 1347 auto result = queries->findInboxTopLevel(); 1348 TestHelpers::waitForEmptyJobQueue(); 1349 QCOMPARE(result->data().size(), 2); 1350 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1351 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 1352 1353 // WHEN 1354 data.modifyCollection(GenCollection(data.collection(43)).selected(false)); 1355 TestHelpers::waitForEmptyJobQueue(); 1356 1357 // THEN 1358 QCOMPARE(result->data().size(), 1); 1359 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1360 } 1361 1362 void shouldLookInAllWorkdayReportedForAllTasks_data() 1363 { 1364 QTest::addColumn<bool>("isExpectedInWorkday"); 1365 QTest::addColumn<Akonadi::Item>("item2"); 1366 1367 const auto today = Utils::DateTime::currentDate(); 1368 1369 QTest::newRow("todayTask") << true 1370 << Akonadi::Item(GenTodo() 1371 .withStartDate(today) 1372 .withDueDate(today)); 1373 1374 QTest::newRow("pastTask") << true 1375 << Akonadi::Item(GenTodo() 1376 .withStartDate(today.addDays(-42)) 1377 .withDueDate(today.addDays(-41))); 1378 1379 QTest::newRow("startTodayTask") << true 1380 << Akonadi::Item(GenTodo() 1381 .withStartDate(today)); 1382 1383 QTest::newRow("endTodayTask") << true 1384 << Akonadi::Item(GenTodo() 1385 .withStartDate(today)); 1386 1387 QTest::newRow("futureTask") << false 1388 << Akonadi::Item(GenTodo() 1389 .withStartDate(today.addDays(41)) 1390 .withDueDate(today.addDays(42))); 1391 1392 QTest::newRow("pastDoneTask") << false 1393 << Akonadi::Item(GenTodo() 1394 .withStartDate(today.addDays(-42)) 1395 .withDueDate(today.addDays(-41)) 1396 .done() 1397 .withDoneDate(today.addDays(-30))); 1398 1399 QTest::newRow("todayDoneTask") << true 1400 << Akonadi::Item(GenTodo() 1401 .withStartDate(today) 1402 .withDueDate(today) 1403 .done() 1404 .withDoneDate(today)); 1405 1406 QTest::newRow("startTodayDoneTask") << true 1407 << Akonadi::Item(GenTodo() 1408 .withStartDate(today) 1409 .done() 1410 .withDoneDate(today)); 1411 1412 QTest::newRow("endTodayDoneTask") << true 1413 << Akonadi::Item(GenTodo() 1414 .withDueDate(today) 1415 .done() 1416 .withDoneDate(today)); 1417 } 1418 1419 void shouldLookInAllWorkdayReportedForAllTasks() 1420 { 1421 // GIVEN 1422 const auto today = Utils::DateTime::currentDate(); 1423 AkonadiFakeData data; 1424 1425 // Two top level collections 1426 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1427 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1428 1429 // One task in the first collection 1430 data.createItem(GenTodo().withId(42).withParent(42) 1431 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1432 .withStartDate(today)); 1433 1434 // One task in the second collection (from data driven set) 1435 QFETCH(Akonadi::Item, item2); 1436 data.createItem(GenTodo(item2).withId(43).withParent(43) 1437 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 1438 1439 // WHEN 1440 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1441 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1442 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(createCachingStorage(data, cache), 1443 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1444 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1445 cache)); 1446 auto result = queries->findWorkdayTopLevel(); 1447 result->data(); 1448 result = queries->findWorkdayTopLevel(); // Should not cause any problem or wrong data 1449 1450 // THEN 1451 QVERIFY(result->data().isEmpty()); 1452 TestHelpers::waitForEmptyJobQueue(); 1453 1454 QFETCH(bool, isExpectedInWorkday); 1455 1456 const int sizeExpected = (isExpectedInWorkday) ? 2 : 1; 1457 1458 QCOMPARE(result->data().size(), sizeExpected); 1459 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1460 1461 if (isExpectedInWorkday) 1462 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 1463 } 1464 1465 void shouldLookInAllWorkdayReportedForAllTasksWhenOverrideDate() 1466 { 1467 // GIVEN 1468 qputenv("ZANSHIN_OVERRIDE_DATE", "2015-03-10"); 1469 const auto today = Utils::DateTime::currentDate(); 1470 AkonadiFakeData data; 1471 1472 // Two top level collections 1473 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1474 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1475 1476 // One task in the first collection 1477 data.createItem(GenTodo().withId(42).withParent(42) 1478 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1479 .withStartDate(today)); 1480 1481 // One task in the second collection 1482 data.createItem(GenTodo().withId(43).withParent(43) 1483 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 1484 .withStartDate(today)); 1485 1486 // WHEN 1487 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1488 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1489 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(createCachingStorage(data, cache), 1490 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1491 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1492 cache)); 1493 auto result = queries->findWorkdayTopLevel(); 1494 result->data(); 1495 result = queries->findWorkdayTopLevel(); // Should not cause any problem or wrong data 1496 1497 // THEN 1498 QVERIFY(result->data().isEmpty()); 1499 TestHelpers::waitForEmptyJobQueue(); 1500 1501 QCOMPARE(result->data().size(), 2); 1502 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1503 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 1504 } 1505 1506 void shouldPollForCurrentDayToListWorkday() 1507 { 1508 // GIVEN 1509 qputenv("ZANSHIN_OVERRIDE_DATE", "2015-03-10"); 1510 const auto today = Utils::DateTime::currentDate(); 1511 AkonadiFakeData data; 1512 1513 // Two top level collections 1514 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1515 data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent()); 1516 1517 // One task in the first collection 1518 data.createItem(GenTodo().withId(42).withParent(42) 1519 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1520 .withStartDate(today)); 1521 1522 // One task in the second collection 1523 data.createItem(GenTodo().withId(43).withParent(43) 1524 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 1525 .withStartDate(today.addDays(1))); 1526 1527 QScopedPointer<Domain::TaskQueries> queries; 1528 { 1529 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1530 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1531 auto akqueries = new Akonadi::TaskQueries(createCachingStorage(data, cache), 1532 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1533 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1534 cache); 1535 QCOMPARE(akqueries->workdayPollInterval(), 30000); 1536 akqueries->setWorkdayPollInterval(500); 1537 queries.reset(akqueries); 1538 } 1539 auto result = queries->findWorkdayTopLevel(); 1540 TestHelpers::waitForEmptyJobQueue(); 1541 QCOMPARE(result->data().size(), 1); 1542 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1543 1544 // WHEN 1545 qputenv("ZANSHIN_OVERRIDE_DATE", "2015-03-11"); 1546 QTest::qWait(1000); 1547 TestHelpers::waitForEmptyJobQueue(); 1548 1549 // THEN 1550 QCOMPARE(result->data().size(), 2); 1551 QCOMPARE(result->data().at(0)->title(), QStringLiteral("42")); 1552 QCOMPARE(result->data().at(1)->title(), QStringLiteral("43")); 1553 } 1554 1555 void shouldNotListWorkdayTasksTwiceIfTheyHaveAParentInWorkday() 1556 { 1557 // GIVEN 1558 const auto today = Utils::DateTime::currentDate(); 1559 AkonadiFakeData data; 1560 1561 // One top level collection 1562 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1563 1564 // One context item 1565 data.createItem(GenTodo().withParent(42).withId(1).withUid("ctx-42").withTitle(QStringLiteral("Context 1")).asContext()); 1566 1567 // Five tasks in the collection, two start today, three not, all forming an ancestry line 1568 data.createItem(GenTodo().withParent(42).withId(42).withTitle(QStringLiteral("42")).withUid("42")); 1569 data.createItem(GenTodo().withParent(42).withId(43).withTitle(QStringLiteral("43")).withUid("43").withParentUid("42").withStartDate(today)); 1570 data.createItem(GenTodo().withParent(42).withId(44).withTitle(QStringLiteral("44")).withUid("44").withParentUid("43")); 1571 data.createItem(GenTodo().withParent(42).withId(45).withTitle(QStringLiteral("45")).withUid("45").withParentUid("44").withStartDate(today)); 1572 data.createItem(GenTodo().withParent(42).withId(46).withTitle(QStringLiteral("46")).withUid("46").withParentUid("45")); 1573 1574 // WHEN 1575 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1576 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1577 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(createCachingStorage(data, cache), 1578 Akonadi::Serializer::Ptr(new Akonadi::Serializer), 1579 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1580 cache)); 1581 auto result = queries->findWorkdayTopLevel(); 1582 result->data(); 1583 result = queries->findWorkdayTopLevel(); // Should not cause any problem or wrong data 1584 1585 // THEN 1586 QVERIFY(result->data().isEmpty()); 1587 TestHelpers::waitForEmptyJobQueue(); 1588 1589 QCOMPARE(result->data().size(), 1); 1590 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 1591 1592 // Should not change anything 1593 result = queries->findWorkdayTopLevel(); 1594 TestHelpers::waitForEmptyJobQueue(); 1595 1596 QCOMPARE(result->data().size(), 1); 1597 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 1598 } 1599 1600 void findProjectShouldLookInCollection() 1601 { 1602 // GIVEN 1603 AkonadiFakeData data; 1604 1605 // One top level collection 1606 auto collection = GenCollection().withId(42).withRootAsParent().withTaskContent(); 1607 data.createCollection(collection); 1608 1609 // Three tasks in the collection (two being children of the first one) 1610 data.createItem(GenTodo().withId(42).asProject().withParent(42) 1611 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42"))); 1612 data.createItem(GenTodo().withId(43).withParent(42) 1613 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")) 1614 .withParentUid(QStringLiteral("uid-42"))); 1615 data.createItem(GenTodo().withId(44).withParent(42) 1616 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")) 1617 .withParentUid(QStringLiteral("uid-42"))); 1618 1619 // WHEN 1620 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1621 1622 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1623 auto storage = createCachingStorage(data, cache); 1624 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1625 serializer, 1626 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1627 cache)); 1628 auto task = serializer->createTaskFromItem(data.item(44)); 1629 // populate cache for collection 1630 auto *fetchJob = storage->fetchItems(collection, nullptr); 1631 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1632 1633 auto result = queries->findProject(task); 1634 1635 // THEN 1636 QVERIFY(result); 1637 TestHelpers::waitForEmptyJobQueue(); 1638 QCOMPARE(result->data().size(), 1); 1639 QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); 1640 1641 // Should not change anything 1642 result = queries->findProject(task); 1643 1644 QCOMPARE(result->data().size(), 1); 1645 QCOMPARE(result->data().at(0)->name(), QStringLiteral("42")); 1646 } 1647 1648 void findProjectShouldReactToRelationshipChange() 1649 { 1650 // GIVEN 1651 AkonadiFakeData data; 1652 1653 // One top level collection 1654 const Akonadi::Collection::Id colId = 42; 1655 auto collection = GenCollection().withId(colId).withRootAsParent().withTaskContent(); 1656 data.createCollection(collection); 1657 1658 // Three tasks in the collection (two being children of the first one) 1659 // 1->2->3 (project) where 1 changes to 1->4->5 (project) 1660 data.createItem(GenTodo().withId(3).asProject().withParent(colId) 1661 .withTitle(QStringLiteral("Project 3")).withUid(QStringLiteral("uid-3"))); 1662 data.createItem(GenTodo().withId(2).withParent(colId) 1663 .withTitle(QStringLiteral("Intermediate item 2")).withUid(QStringLiteral("uid-2")) 1664 .withParentUid(QStringLiteral("uid-3"))); 1665 data.createItem(GenTodo().withId(1).withParent(colId) 1666 .withTitle(QStringLiteral("Item 1")).withUid(QStringLiteral("uid-1")) 1667 .withParentUid(QStringLiteral("uid-2"))); 1668 data.createItem(GenTodo().withId(5).asProject().withParent(colId) 1669 .withTitle(QStringLiteral("Project 5")).withUid(QStringLiteral("uid-5"))); 1670 data.createItem(GenTodo().withId(4).withParent(colId) 1671 .withTitle(QStringLiteral("Intermediate item 4")).withUid(QStringLiteral("uid-4")) 1672 .withParentUid(QStringLiteral("uid-5"))); 1673 1674 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1675 1676 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1677 auto storage = createCachingStorage(data, cache); 1678 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1679 serializer, 1680 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1681 cache)); 1682 auto task = serializer->createTaskFromItem(data.item(1)); 1683 1684 auto result = queries->findProject(task); 1685 1686 QVERIFY(result); 1687 TestHelpers::waitForEmptyJobQueue(); 1688 QCOMPARE(result->data().size(), 1); 1689 QCOMPARE(result->data().at(0)->name(), QStringLiteral("Project 3")); 1690 1691 // WHEN 1692 data.modifyItem(GenTodo(data.item(1)).withParentUid(QStringLiteral("uid-4"))); 1693 1694 // THEN 1695 TestHelpers::waitForEmptyJobQueue(); 1696 QCOMPARE(result->data().size(), 1); 1697 QCOMPARE(result->data().at(0)->name(), QStringLiteral("Project 5")); 1698 } 1699 1700 void findProjectShouldReactToIntermediateParentChange() 1701 { 1702 // GIVEN 1703 AkonadiFakeData data; 1704 1705 // One top level collection 1706 const Akonadi::Collection::Id colId = 42; 1707 data.createCollection(GenCollection().withId(colId).withRootAsParent().withTaskContent()); 1708 1709 // Three tasks in the collection (two being children of the first one) 1710 // 1->2->3 (project) where 2 changes to 1->2->4 (project) 1711 data.createItem(GenTodo().withId(3).asProject().withParent(colId) 1712 .withTitle(QStringLiteral("Project 3")).withUid(QStringLiteral("uid-3"))); 1713 data.createItem(GenTodo().withId(2).withParent(colId) 1714 .withTitle(QStringLiteral("Intermediate item 2")).withUid(QStringLiteral("uid-2")) 1715 .withParentUid(QStringLiteral("uid-3"))); 1716 data.createItem(GenTodo().withId(1).withParent(colId) 1717 .withTitle(QStringLiteral("Item 1")).withUid(QStringLiteral("uid-1")) 1718 .withParentUid(QStringLiteral("uid-2"))); 1719 data.createItem(GenTodo().withId(4).asProject().withParent(colId) 1720 .withTitle(QStringLiteral("Project 4")).withUid(QStringLiteral("uid-4"))); 1721 1722 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1723 1724 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1725 auto storage = createCachingStorage(data, cache); 1726 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1727 serializer, 1728 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1729 cache)); 1730 auto task = serializer->createTaskFromItem(data.item(1)); 1731 1732 auto result = queries->findProject(task); 1733 1734 QVERIFY(result); 1735 TestHelpers::waitForEmptyJobQueue(); 1736 QCOMPARE(result->data().size(), 1); 1737 QCOMPARE(result->data().at(0)->name(), QStringLiteral("Project 3")); 1738 1739 // WHEN 1740 data.modifyItem(GenTodo(data.item(2)).withParentUid(QStringLiteral("uid-4"))); 1741 1742 // THEN 1743 TestHelpers::waitForEmptyJobQueue(); 1744 QCOMPARE(result->data().size(), 1); 1745 QCOMPARE(result->data().at(0)->name(), QStringLiteral("Project 4")); 1746 1747 // AND WHEN 1748 data.removeItem(GenTodo(data.item(2))); 1749 1750 // THEN 1751 TestHelpers::waitForEmptyJobQueue(); 1752 QCOMPARE(result->data().size(), 0); 1753 } 1754 1755 void findProjectShouldReactToChildItemRemoved() 1756 { 1757 // GIVEN 1758 AkonadiFakeData data; 1759 1760 // One top level collection 1761 const Akonadi::Collection::Id colId = 42; 1762 data.createCollection(GenCollection().withId(colId).withRootAsParent().withTaskContent()); 1763 1764 // Three task in the collection: 1->2(project) 1765 data.createItem(GenTodo().withId(2).asProject().withParent(colId) 1766 .withTitle(QStringLiteral("Project 2")).withUid(QStringLiteral("uid-2"))); 1767 data.createItem(GenTodo().withId(1).withParent(colId) 1768 .withTitle(QStringLiteral("Item 1")).withUid(QStringLiteral("uid-1")) 1769 .withParentUid(QStringLiteral("uid-2"))); 1770 1771 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1772 1773 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1774 auto storage = createCachingStorage(data, cache); 1775 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1776 serializer, 1777 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1778 cache)); 1779 auto task = serializer->createTaskFromItem(data.item(1)); 1780 auto result = queries->findProject(task); 1781 QVERIFY(result); 1782 TestHelpers::waitForEmptyJobQueue(); 1783 QCOMPARE(result->data().size(), 1); 1784 QCOMPARE(result->data().at(0)->name(), QStringLiteral("Project 2")); 1785 1786 // WHEN 1787 data.removeItem(Akonadi::Item(1)); 1788 1789 // THEN 1790 TestHelpers::waitForEmptyJobQueue(); 1791 QCOMPARE(result->data().size(), 0); 1792 } 1793 1794 void findContextsShouldLookInAllCollections() 1795 { 1796 // GIVEN 1797 AkonadiFakeData data; 1798 1799 // One top level collection 1800 auto collection1 = GenCollection().withId(42).withRootAsParent().withTaskContent(); 1801 data.createCollection(collection1); 1802 auto collection2 = GenCollection().withId(43).withRootAsParent().withTaskContent(); 1803 data.createCollection(collection2); 1804 1805 // One task in collection1, one context in collection1, one context in collection2 1806 data.createItem(GenTodo().withId(42).withParent(42) 1807 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1808 .withContexts({ QStringLiteral("uid-43"), QStringLiteral("uid-44") })); 1809 data.createItem(GenTodo().withId(43).withParent(42).asContext() 1810 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 1811 data.createItem(GenTodo().withId(44).withParent(43).asContext() 1812 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); 1813 1814 // WHEN 1815 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1816 1817 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1818 auto storage = createCachingStorage(data, cache); 1819 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1820 serializer, 1821 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1822 cache)); 1823 auto task = serializer->createTaskFromItem(data.item(42)); 1824 // populate cache for collection 1825 auto *fetchJob = storage->fetchItems(collection1, nullptr); 1826 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1827 fetchJob = storage->fetchItems(collection2, nullptr); 1828 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1829 1830 auto result = queries->findContexts(task); 1831 1832 // THEN 1833 QVERIFY(result); 1834 TestHelpers::waitForEmptyJobQueue(); 1835 QCOMPARE(result->data().size(), 2); 1836 QCOMPARE(result->data().at(0)->name(), QStringLiteral("43")); 1837 QCOMPARE(result->data().at(1)->name(), QStringLiteral("44")); 1838 1839 // Should not change anything 1840 result = queries->findContexts(task); 1841 1842 QCOMPARE(result->data().size(), 2); 1843 QCOMPARE(result->data().at(0)->name(), QStringLiteral("43")); 1844 QCOMPARE(result->data().at(1)->name(), QStringLiteral("44")); 1845 } 1846 1847 void findContextsShouldReactToRelationshipChange() 1848 { 1849 // GIVEN 1850 AkonadiFakeData data; 1851 1852 // One top level collection 1853 auto collection1 = GenCollection().withId(42).withRootAsParent().withTaskContent(); 1854 data.createCollection(collection1); 1855 auto collection2 = GenCollection().withId(43).withRootAsParent().withTaskContent(); 1856 data.createCollection(collection2); 1857 1858 // One task in collection1, one context in collection1, two contexts in collection2 1859 data.createItem(GenTodo().withId(42).withParent(42) 1860 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1861 .withContexts({ QStringLiteral("uid-43"), QStringLiteral("uid-44") })); 1862 data.createItem(GenTodo().withId(43).withParent(42).asContext() 1863 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 1864 data.createItem(GenTodo().withId(44).withParent(43).asContext() 1865 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); 1866 data.createItem(GenTodo().withId(45).withParent(43).asContext() 1867 .withTitle(QStringLiteral("45")).withUid(QStringLiteral("uid-45"))); 1868 1869 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1870 1871 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1872 auto storage = createCachingStorage(data, cache); 1873 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1874 serializer, 1875 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1876 cache)); 1877 auto task = serializer->createTaskFromItem(data.item(42)); 1878 // populate cache for collection 1879 auto *fetchJob = storage->fetchItems(collection1, nullptr); 1880 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1881 fetchJob = storage->fetchItems(collection2, nullptr); 1882 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1883 1884 auto result = queries->findContexts(task); 1885 1886 QVERIFY(result); 1887 TestHelpers::waitForEmptyJobQueue(); 1888 QCOMPARE(result->data().size(), 2); 1889 QCOMPARE(result->data().at(0)->name(), QStringLiteral("43")); 1890 QCOMPARE(result->data().at(1)->name(), QStringLiteral("44")); 1891 1892 // WHEN 1893 data.modifyItem(GenTodo(data.item(42)).withContexts({ QStringLiteral("uid-43"), QStringLiteral("uid-45") })); 1894 1895 // THEN 1896 TestHelpers::waitForEmptyJobQueue(); 1897 QCOMPARE(result->data().size(), 2); 1898 QCOMPARE(result->data().at(0)->name(), QStringLiteral("43")); 1899 QCOMPARE(result->data().at(1)->name(), QStringLiteral("45")); 1900 1901 // WHEN 1902 data.modifyItem(GenTodo(data.item(42)).withContexts({ QStringLiteral("uid-45") })); 1903 1904 // THEN 1905 TestHelpers::waitForEmptyJobQueue(); 1906 QCOMPARE(result->data().size(), 1); 1907 QCOMPARE(result->data().at(0)->name(), QStringLiteral("45")); 1908 1909 // WHEN 1910 data.modifyItem(GenTodo(data.item(42)).withContexts({})); 1911 1912 // THEN 1913 TestHelpers::waitForEmptyJobQueue(); 1914 QCOMPARE(result->data().size(), 0); 1915 } 1916 1917 void findContextsShouldReactToItemRemoved() 1918 { 1919 // GIVEN 1920 AkonadiFakeData data; 1921 1922 // One top level collection 1923 auto collection1 = GenCollection().withId(42).withRootAsParent().withTaskContent(); 1924 data.createCollection(collection1); 1925 auto collection2 = GenCollection().withId(43).withRootAsParent().withTaskContent(); 1926 data.createCollection(collection2); 1927 1928 // One task in collection1, one context in collection1, one context in collection2 1929 data.createItem(GenTodo().withId(42).withParent(42) 1930 .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")) 1931 .withContexts({ QStringLiteral("uid-43"), QStringLiteral("uid-44") })); 1932 data.createItem(GenTodo().withId(43).withParent(42).asContext() 1933 .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))); 1934 data.createItem(GenTodo().withId(44).withParent(43).asContext() 1935 .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))); 1936 1937 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1938 1939 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1940 auto storage = createCachingStorage(data, cache); 1941 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1942 serializer, 1943 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1944 cache)); 1945 auto task = serializer->createTaskFromItem(data.item(42)); 1946 // populate cache for collection 1947 auto *fetchJob = storage->fetchItems(collection1, nullptr); 1948 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1949 fetchJob = storage->fetchItems(collection2, nullptr); 1950 QVERIFY2(fetchJob->kjob()->exec(), qPrintable(fetchJob->kjob()->errorString())); 1951 1952 auto result = queries->findContexts(task); 1953 1954 QVERIFY(result); 1955 TestHelpers::waitForEmptyJobQueue(); 1956 QCOMPARE(result->data().size(), 2); 1957 QCOMPARE(result->data().at(0)->name(), QStringLiteral("43")); 1958 QCOMPARE(result->data().at(1)->name(), QStringLiteral("44")); 1959 1960 // WHEN 1961 data.removeItem(Akonadi::Item(42)); 1962 1963 // THEN 1964 TestHelpers::waitForEmptyJobQueue(); 1965 QCOMPARE(result->data().size(), 0); 1966 } 1967 1968 void shouldOnlyReturnTopLevelTasks() 1969 { 1970 // GIVEN 1971 AkonadiFakeData data; 1972 1973 // One collection 1974 data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent()); 1975 1976 // One empty project 1977 data.createItem(GenTodo().withId(1).asProject().withParent(42) 1978 .withTitle(QStringLiteral("Empty Project")).withUid(QStringLiteral("project-1"))); 1979 // One real project 1980 data.createItem(GenTodo().withId(2).asProject().withParent(42) 1981 .withTitle(QStringLiteral("Real Project")).withUid(QStringLiteral("project-2"))); 1982 1983 // Two toplevel tasks in the second collection, one with a child 1984 data.createItem(GenTodo().withId(3).withParent(42).withTitle(QStringLiteral("43")).withUid("parent-43").withParentUid("project-2")); 1985 data.createItem(GenTodo().withId(4).withParent(42).withTitle(QStringLiteral("44")).withParentUid(QStringLiteral("2"))); // non-existing parent 1986 data.createItem(GenTodo().withId(5).withParent(42).withTitle(QStringLiteral("45")).withParentUid(QStringLiteral("parent-43"))); // existing parent 1987 1988 // WHEN 1989 auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer); 1990 auto cache = Akonadi::Cache::Ptr::create(serializer, Akonadi::MonitorInterface::Ptr(data.createMonitor())); 1991 auto storage = createCachingStorage(data, cache); 1992 QScopedPointer<Domain::TaskQueries> queries(new Akonadi::TaskQueries(storage, 1993 serializer, 1994 Akonadi::MonitorInterface::Ptr(data.createMonitor()), 1995 cache)); 1996 auto result = queries->findTopLevel(); 1997 result->data(); 1998 result = queries->findTopLevel(); // Should not cause any problem or wrong data 1999 2000 // THEN 2001 QVERIFY(result->data().isEmpty()); 2002 TestHelpers::waitForEmptyJobQueue(); 2003 2004 QCOMPARE(result->data().size(), 2); 2005 QCOMPARE(result->data().at(0)->title(), QStringLiteral("43")); 2006 QCOMPARE(result->data().at(1)->title(), QStringLiteral("44")); 2007 } 2008 2009 }; 2010 2011 ZANSHIN_TEST_MAIN(AkonadiTaskQueriesTest) 2012 2013 #include "akonaditaskqueriestest.moc"