File indexing completed on 2025-01-05 04:59:52

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/akonadiprojectqueries.h"
0010 #include "akonadi/akonadiserializer.h"
0011 
0012 #include "testlib/akonadifakedata.h"
0013 #include "testlib/gencollection.h"
0014 #include "testlib/gentodo.h"
0015 #include "testlib/testhelpers.h"
0016 
0017 using namespace Testlib;
0018 
0019 class AkonadiProjectQueriesTest : public QObject
0020 {
0021     Q_OBJECT
0022 private slots:
0023     void shouldLookInAllReportedForAllProjects()
0024     {
0025         // GIVEN
0026         AkonadiFakeData data;
0027 
0028         // Two top level collections
0029         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0030         data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent());
0031 
0032         // One project in the first collection
0033         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0034 
0035         // Two projects in the second collection
0036         data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43")).asProject());
0037         data.createItem(GenTodo().withId(44).withParent(43).withTitle(QStringLiteral("44")).asProject());
0038 
0039         // WHEN
0040         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0041                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0042                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0043         auto result = queries->findAll();
0044         result->data();
0045         result = queries->findAll(); // Should not cause any problem or wrong data
0046 
0047         // THEN
0048         QVERIFY(result->data().isEmpty());
0049         TestHelpers::waitForEmptyJobQueue();
0050 
0051         QCOMPARE(result->data().size(), 3);
0052         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0053         QCOMPARE(result->data().at(1)->name(), QStringLiteral("43"));
0054         QCOMPARE(result->data().at(2)->name(), QStringLiteral("44"));
0055     }
0056 
0057     void shouldIgnoreItemsWhichAreNotProjects()
0058     {
0059         // GIVEN
0060         AkonadiFakeData data;
0061 
0062         // One top level collection
0063         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0064 
0065         // One project and one regular task in the collection
0066         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0067         data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")));
0068 
0069         // WHEN
0070         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0071                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0072                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0073         auto result = queries->findAll();
0074         QVERIFY(result->data().isEmpty());
0075         TestHelpers::waitForEmptyJobQueue();
0076 
0077         // THEN
0078         QCOMPARE(result->data().size(), 1);
0079         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0080     }
0081 
0082     void shouldReactToItemAddsForProjectsOnly()
0083     {
0084         // GIVEN
0085         AkonadiFakeData data;
0086 
0087         // One empty collection
0088         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0089 
0090         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0091                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0092                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0093         auto result = queries->findAll();
0094         TestHelpers::waitForEmptyJobQueue();
0095         QVERIFY(result->data().isEmpty());
0096 
0097         // WHEN
0098         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0099         data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")));
0100 
0101         // THEN
0102         QCOMPARE(result->data().size(), 1);
0103         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0104     }
0105 
0106     void shouldReactToItemRemovesForAllProjects()
0107     {
0108         // GIVEN
0109         AkonadiFakeData data;
0110 
0111         // One top level collection
0112         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0113 
0114         // Three projects in the collection
0115         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0116         data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).asProject());
0117         data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).asProject());
0118 
0119         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0120                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0121                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0122         auto result = queries->findAll();
0123         TestHelpers::waitForEmptyJobQueue();
0124         QCOMPARE(result->data().size(), 3);
0125 
0126         // WHEN
0127         data.removeItem(Akonadi::Item(43));
0128 
0129         // THEN
0130         QCOMPARE(result->data().size(), 2);
0131         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0132         QCOMPARE(result->data().at(1)->name(), QStringLiteral("44"));
0133     }
0134 
0135     void shouldReactToItemChangesForAllProjects()
0136     {
0137         // GIVEN
0138         AkonadiFakeData data;
0139 
0140         // One top level collection
0141         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0142 
0143         // Three projects in the collection
0144         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0145         data.createItem(GenTodo().withId(43).withParent(42).withTitle(QStringLiteral("43")).asProject());
0146         data.createItem(GenTodo().withId(44).withParent(42).withTitle(QStringLiteral("44")).asProject());
0147 
0148         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0149                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0150                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0151         auto result = queries->findAll();
0152         // Even though the pointer didn't change it's convenient to user if we call
0153         // the replace handlers
0154         bool replaceHandlerCalled = false;
0155         result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Project::Ptr &, int) {
0156                                           replaceHandlerCalled = true;
0157                                       });
0158         TestHelpers::waitForEmptyJobQueue();
0159         QCOMPARE(result->data().size(), 3);
0160 
0161         // WHEN
0162         data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis")));
0163 
0164         // THEN
0165         QCOMPARE(result->data().size(), 3);
0166         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0167         QCOMPARE(result->data().at(1)->name(), QStringLiteral("43bis"));
0168         QCOMPARE(result->data().at(2)->name(), QStringLiteral("44"));
0169         QVERIFY(replaceHandlerCalled);
0170     }
0171 
0172     void shouldReactToCollectionSelectionChangesForAllProjects()
0173     {
0174         // GIVEN
0175         AkonadiFakeData data;
0176 
0177         // Two top level collections
0178         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0179         data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent());
0180 
0181         // Two projects, one in each collection
0182         data.createItem(GenTodo().withId(42).withParent(42).withTitle(QStringLiteral("42")).asProject());
0183         data.createItem(GenTodo().withId(43).withParent(43).withTitle(QStringLiteral("43")).asProject());
0184 
0185         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0186                                                                                    Akonadi::Serializer::Ptr(new Akonadi::Serializer),
0187                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0188         auto result = queries->findAll();
0189         TestHelpers::waitForEmptyJobQueue();
0190         QCOMPARE(result->data().size(), 2);
0191         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0192         QCOMPARE(result->data().at(1)->name(), QStringLiteral("43"));
0193 
0194         // WHEN
0195         data.modifyCollection(GenCollection(data.collection(43)).selected(false));
0196         TestHelpers::waitForEmptyJobQueue();
0197 
0198         // THEN
0199         QCOMPARE(result->data().size(), 1);
0200         QCOMPARE(result->data().at(0)->name(), QStringLiteral("42"));
0201     }
0202 
0203     void shouldLookOnlyInParentCollectionForProjectTopLevel()
0204     {
0205         // GIVEN
0206         AkonadiFakeData data;
0207 
0208         // Two top level collections
0209         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0210         data.createCollection(GenCollection().withId(43).withRootAsParent().withTaskContent());
0211 
0212         // One project and two tasks in the first collection (one task being child of the project)
0213         data.createItem(GenTodo().withId(42).withParent(42)
0214                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0215         data.createItem(GenTodo().withId(43).withParent(42)
0216                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))
0217                                  .withParentUid(QStringLiteral("uid-42")));
0218         data.createItem(GenTodo().withId(44).withParent(42)
0219                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44")));
0220 
0221         // Two tasks in the second collection (one having the project uid as parent)
0222         data.createItem(GenTodo().withId(45).withParent(43)
0223                                  .withTitle(QStringLiteral("45")).withParentUid(QStringLiteral("uid-42")));
0224         data.createItem(GenTodo().withId(46).withParent(43).withTitle(QStringLiteral("46")));
0225 
0226         // WHEN
0227         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0228         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0229                                                                                    serializer,
0230                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0231         auto project = serializer->createProjectFromItem(data.item(42));
0232         auto result = queries->findTopLevel(project);
0233         result->data();
0234         result = queries->findTopLevel(project); // Should not cause any problem or wrong data
0235 
0236         // THEN
0237         QVERIFY(result->data().isEmpty());
0238         TestHelpers::waitForEmptyJobQueue();
0239 
0240         QCOMPARE(result->data().size(), 1);
0241         QCOMPARE(result->data().at(0)->title(), QStringLiteral("43"));
0242 
0243         // Should not change nothing
0244         result = queries->findTopLevel(project);
0245 
0246         QCOMPARE(result->data().size(), 1);
0247         QCOMPARE(result->data().at(0)->title(), QStringLiteral("43"));
0248     }
0249 
0250     void shouldNotCrashWhenWeAskAgainTheSameTopLevelTasks()
0251     {
0252         // GIVEN
0253         AkonadiFakeData data;
0254 
0255         // One top level collection
0256         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0257 
0258         // One project in the collection
0259         data.createItem(GenTodo().withId(42).withParent(42)
0260                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0261 
0262         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0263         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0264                                                                                    serializer,
0265                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0266         auto project = serializer->createProjectFromItem(data.item(42));
0267 
0268         // The bug we're trying to hit here is the following:
0269         //  - when findChildren is called the first time a provider is created internally
0270         //  - result is deleted at the end of the loop, no one holds the provider with
0271         //    a strong reference anymore so it is deleted as well
0272         //  - when findChildren is called the second time, there's a risk of a dangling
0273         //    pointer if the recycling of providers is wrongly implemented which can lead
0274         //    to a crash, if it is properly done no crash will occur
0275         for (int i = 0; i < 2; i++) {
0276             // WHEN * 2
0277             auto result = queries->findTopLevel(project);
0278 
0279             // THEN * 2
0280             QVERIFY(result->data().isEmpty());
0281             TestHelpers::waitForEmptyJobQueue();
0282             QVERIFY(result->data().isEmpty());
0283         }
0284     }
0285 
0286     void shouldReactToItemAddsForTopLevelTask()
0287     {
0288         // GIVEN
0289         AkonadiFakeData data;
0290 
0291         // One top level collection
0292         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0293 
0294         // One project in the collection
0295         data.createItem(GenTodo().withId(42).withParent(42)
0296                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0297 
0298         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0299         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0300                                                                                    serializer,
0301                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0302         auto project = serializer->createProjectFromItem(data.item(42));
0303         auto result = queries->findTopLevel(project);
0304         TestHelpers::waitForEmptyJobQueue();
0305         QVERIFY(result->data().isEmpty());
0306 
0307         // WHEN
0308         data.createItem(GenTodo().withId(43).withParent(42)
0309                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))
0310                                  .withParentUid(QStringLiteral("uid-42")));
0311         data.createItem(GenTodo().withId(44).withParent(42)
0312                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0313                                  .withParentUid(QStringLiteral("uid-42")));
0314 
0315         // THEN
0316         QCOMPARE(result->data().size(), 2);
0317         QCOMPARE(result->data().at(0)->title(), QStringLiteral("43"));
0318         QCOMPARE(result->data().at(1)->title(), QStringLiteral("44"));
0319     }
0320 
0321     void shouldReactToItemChangesForTopLevelTasks()
0322     {
0323         // GIVEN
0324         AkonadiFakeData data;
0325 
0326         // One top level collection
0327         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0328 
0329         // One project and two tasks in the collection (tasks being children of the project)
0330         data.createItem(GenTodo().withId(42).withParent(42)
0331                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0332         data.createItem(GenTodo().withId(43).withParent(42)
0333                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))
0334                                  .withParentUid(QStringLiteral("uid-42")));
0335         data.createItem(GenTodo().withId(44).withParent(42)
0336                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0337                                  .withParentUid(QStringLiteral("uid-42")));
0338 
0339         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0340         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0341                                                                                    serializer,
0342                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0343         auto project = serializer->createProjectFromItem(data.item(42));
0344         auto result = queries->findTopLevel(project);
0345 
0346         bool replaceHandlerCalled = false;
0347         result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) {
0348                                           replaceHandlerCalled = true;
0349                                       });
0350         TestHelpers::waitForEmptyJobQueue();
0351         QCOMPARE(result->data().size(), 2);
0352 
0353         // WHEN
0354         data.modifyItem(GenTodo(data.item(43)).withTitle(QStringLiteral("43bis")));
0355 
0356         // THEN
0357         QCOMPARE(result->data().size(), 2);
0358         QCOMPARE(result->data().at(0)->title(), QStringLiteral("43bis"));
0359         QCOMPARE(result->data().at(1)->title(), QStringLiteral("44"));
0360 
0361         QVERIFY(replaceHandlerCalled);
0362     }
0363 
0364     void shouldRemoveItemFromCorrespondingResultWhenRelatedItemChangesForTopLevelTask()
0365     {
0366         // GIVEN
0367         AkonadiFakeData data;
0368 
0369         // One top level collection
0370         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0371 
0372         // One project and two tasks in the collection (tasks being children of the project)
0373         data.createItem(GenTodo().withId(42).withParent(42)
0374                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0375         data.createItem(GenTodo().withId(43).withParent(42)
0376                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))
0377                                  .withParentUid(QStringLiteral("uid-42")));
0378         data.createItem(GenTodo().withId(44).withParent(42)
0379                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0380                                  .withParentUid(QStringLiteral("uid-42")));
0381 
0382         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0383         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0384                                                                                    serializer,
0385                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0386         auto project = serializer->createProjectFromItem(data.item(42));
0387         auto result = queries->findTopLevel(project);
0388         TestHelpers::waitForEmptyJobQueue();
0389         QCOMPARE(result->data().size(), 2);
0390 
0391         // WHEN
0392         data.modifyItem(GenTodo(data.item(43)).withParentUid(QLatin1StringView("")));
0393 
0394         // THEN
0395         QCOMPARE(result->data().size(), 1);
0396         QCOMPARE(result->data().at(0)->title(), QStringLiteral("44"));
0397     }
0398 
0399     void shouldAddItemToCorrespondingResultWhenRelatedItemChangeForChildrenTask()
0400     {
0401         // GIVEN
0402         AkonadiFakeData data;
0403 
0404         // One top level collection
0405         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0406 
0407         // One project and two tasks in the collection (one being child of the project)
0408         data.createItem(GenTodo().withId(42).withParent(42)
0409                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0410         data.createItem(GenTodo().withId(43).withParent(42)
0411                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")));
0412         data.createItem(GenTodo().withId(44).withParent(42)
0413                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0414                                  .withParentUid(QStringLiteral("uid-42")));
0415 
0416         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0417         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0418                                                                                    serializer,
0419                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0420         auto project = serializer->createProjectFromItem(data.item(42));
0421         auto result = queries->findTopLevel(project);
0422 
0423         bool replaceHandlerCalled = false;
0424         result->addPostReplaceHandler([&replaceHandlerCalled](const Domain::Task::Ptr &, int) {
0425                                           replaceHandlerCalled = true;
0426                                       });
0427         TestHelpers::waitForEmptyJobQueue();
0428         QCOMPARE(result->data().size(), 1);
0429 
0430         // WHEN
0431         data.modifyItem(GenTodo(data.item(43)).withParentUid(QStringLiteral("uid-42")));
0432 
0433         // THEN
0434         QCOMPARE(result->data().size(), 2);
0435         QCOMPARE(result->data().at(0)->title(), QStringLiteral("44"));
0436         QCOMPARE(result->data().at(1)->title(), QStringLiteral("43"));
0437 
0438         QVERIFY(!replaceHandlerCalled);
0439     }
0440 
0441     void shouldMoveItemToCorrespondingResultWhenRelatedItemChangeForTopLevelTasks()
0442     {
0443         // GIVEN
0444         AkonadiFakeData data;
0445 
0446         // One top level collection
0447         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0448 
0449         // Two project and one task in the collection (task being child of the first project)
0450         data.createItem(GenTodo().withId(42).withParent(42)
0451                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0452         data.createItem(GenTodo().withId(43).withParent(42)
0453                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43")).asProject());
0454         data.createItem(GenTodo().withId(44).withParent(42)
0455                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0456                                  .withParentUid(QStringLiteral("uid-42")));
0457 
0458         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0459         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0460                                                                                    serializer,
0461                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0462         auto project1 = serializer->createProjectFromItem(data.item(42));
0463         auto project2 = serializer->createProjectFromItem(data.item(43));
0464         auto result1 = queries->findTopLevel(project1);
0465         auto result2 = queries->findTopLevel(project2);
0466 
0467         TestHelpers::waitForEmptyJobQueue();
0468         QCOMPARE(result1->data().size(), 1);
0469         QCOMPARE(result1->data().at(0)->title(), QStringLiteral("44"));
0470         QCOMPARE(result2->data().size(), 0);
0471 
0472         // WHEN
0473         data.modifyItem(GenTodo(data.item(44)).withParentUid(QStringLiteral("uid-43")));
0474 
0475         // THEN
0476         QCOMPARE(result1->data().size(), 0);
0477         QCOMPARE(result2->data().size(), 1);
0478         QCOMPARE(result2->data().at(0)->title(), QStringLiteral("44"));
0479     }
0480 
0481     void shouldReactToItemRemovesForTopLevelTasks()
0482     {
0483         // GIVEN
0484         AkonadiFakeData data;
0485 
0486         // One top level collection
0487         data.createCollection(GenCollection().withId(42).withRootAsParent().withTaskContent());
0488 
0489         // One project and two tasks in the collection (tasks being children of the project)
0490         data.createItem(GenTodo().withId(42).withParent(42)
0491                                  .withTitle(QStringLiteral("42")).withUid(QStringLiteral("uid-42")).asProject());
0492         data.createItem(GenTodo().withId(43).withParent(42)
0493                                  .withTitle(QStringLiteral("43")).withUid(QStringLiteral("uid-43"))
0494                                  .withParentUid(QStringLiteral("uid-42")));
0495         data.createItem(GenTodo().withId(44).withParent(42)
0496                                  .withTitle(QStringLiteral("44")).withUid(QStringLiteral("uid-44"))
0497                                  .withParentUid(QStringLiteral("uid-42")));
0498 
0499         auto serializer = Akonadi::Serializer::Ptr(new Akonadi::Serializer);
0500         QScopedPointer<Domain::ProjectQueries> queries(new Akonadi::ProjectQueries(Akonadi::StorageInterface::Ptr(data.createStorage()),
0501                                                                                    serializer,
0502                                                                                    Akonadi::MonitorInterface::Ptr(data.createMonitor())));
0503         auto project = serializer->createProjectFromItem(data.item(42));
0504         auto result = queries->findTopLevel(project);
0505         TestHelpers::waitForEmptyJobQueue();
0506         QCOMPARE(result->data().size(), 2);
0507 
0508         // WHEN
0509         data.removeItem(Akonadi::Item(43));
0510 
0511         // THEN
0512         QCOMPARE(result->data().size(), 1);
0513         QCOMPARE(result->data().at(0)->title(), QStringLiteral("44"));
0514     }
0515 };
0516 
0517 ZANSHIN_TEST_MAIN(AkonadiProjectQueriesTest)
0518 
0519 #include "akonadiprojectqueriestest.moc"