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

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Franck Arrecot <franck.arrecot@gmail.com>
0003    SPDX-FileCopyrightText: 2014 RĂ©mi Benoit <r3m1.benoit@gmail.com>
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 
0008 #include <testlib/qtest_zanshin.h>
0009 
0010 #include "utils/mockobject.h"
0011 
0012 #include "testlib/akonadifakejobs.h"
0013 #include "testlib/akonadifakemonitor.h"
0014 
0015 #include "akonadi/akonadicontextrepository.h"
0016 #include "akonadi/akonadiserializerinterface.h"
0017 #include "akonadi/akonadistorageinterface.h"
0018 
0019 using namespace mockitopp;
0020 using namespace mockitopp::matcher;
0021 
0022 Q_DECLARE_METATYPE(Testlib::AkonadiFakeItemFetchJob*)
0023 
0024 class AkonadiContextRepositoryTest : public QObject
0025 {
0026     Q_OBJECT
0027 private slots:
0028     void shouldCreateContext()
0029     {
0030         // GIVEN
0031         auto source = Domain::DataSource::Ptr::create();
0032         source->setName(QStringLiteral("Source1"));
0033 
0034         // A Context and its corresponding item not existing in akonadi
0035         Akonadi::Item contextItem;
0036         Akonadi::Collection collection(23);
0037         auto context = Domain::Context::Ptr::create();
0038 
0039         // A mock creating job
0040         auto itemCreateJob = new FakeJob(this);
0041 
0042         // Storage mock returning the context-item creation job
0043         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0044         storageMock(&Akonadi::StorageInterface::createItem).when(contextItem, collection)
0045                                                           .thenReturn(itemCreateJob);
0046 
0047         // Serializer mock
0048         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0049         serializerMock(&Akonadi::SerializerInterface::createItemFromContext).when(context).thenReturn(contextItem);
0050         serializerMock(&Akonadi::SerializerInterface::createCollectionFromDataSource).when(source).thenReturn(collection);
0051 
0052         // WHEN
0053         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0054                                                                                              serializerMock.getInstance()));
0055         repository->create(context, source)->exec();
0056 
0057         //THEN
0058         QVERIFY(storageMock(&Akonadi::StorageInterface::createItem).when(contextItem, collection).exactly(1));
0059     }
0060 
0061     void shouldUpdateContext()
0062     {
0063         // GIVEN
0064         Akonadi::Item contextItem;
0065         contextItem.setId(42);
0066         auto context = Domain::Context::Ptr::create();
0067 
0068         // A mock job
0069         auto itemModifyJob = new FakeJob(this);
0070 
0071         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0072         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0073         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0074                                                                                              serializerMock.getInstance()));
0075 
0076         // Storage mock returning the item modify job
0077         storageMock(&Akonadi::StorageInterface::updateItem).when(contextItem, repository.get())
0078                                                            .thenReturn(itemModifyJob);
0079 
0080         // Serializer mock
0081         serializerMock(&Akonadi::SerializerInterface::createItemFromContext).when(context).thenReturn(contextItem);
0082 
0083         // WHEN
0084         repository->update(context)->exec();
0085 
0086         // THEN
0087         QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromContext).when(context).exactly(1));
0088         QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(contextItem, repository.get()).exactly(1));
0089     }
0090 
0091     void shouldRemoveContext()
0092     {
0093         // GIVEN
0094         Akonadi::Item contextItem;
0095         contextItem.setId(42);
0096         auto context = Domain::Context::Ptr::create();
0097 
0098         // A mock job
0099         auto contextItemDeleteJob = new FakeJob(this);
0100 
0101         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0102         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0103         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0104                                                                                              serializerMock.getInstance()));
0105 
0106         // Storage mock returning the mock job
0107         storageMock(&Akonadi::StorageInterface::removeItem).when(contextItem, repository.get())
0108                                                            .thenReturn(contextItemDeleteJob);
0109 
0110         // Serializer mock
0111         serializerMock(&Akonadi::SerializerInterface::createItemFromContext).when(context).thenReturn(contextItem);
0112 
0113         // WHEN
0114         repository->remove(context)->exec();
0115 
0116         // THEN
0117         QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromContext).when(context).exactly(1));
0118         QVERIFY(storageMock(&Akonadi::StorageInterface::removeItem).when(contextItem, repository.get()).exactly(1));
0119     }
0120 
0121     void shouldAssociateATaskToAContext_data()
0122     {
0123         QTest::addColumn<Akonadi::Item>("associatedContextItem");
0124         QTest::addColumn<Akonadi::Item>("item");
0125         QTest::addColumn<Domain::Context::Ptr>("context");
0126         QTest::addColumn<Domain::Task::Ptr>("task");
0127         QTest::addColumn<Testlib::AkonadiFakeItemFetchJob*>("itemFetchJob");
0128         QTest::addColumn<bool>("execJob");
0129 
0130         Akonadi::Collection col(40);
0131 
0132         Akonadi::Item item(42);
0133         item.setParentCollection(col);
0134         Domain::Task::Ptr task(new Domain::Task);
0135 
0136         Akonadi::Item associatedContextItem(43);
0137         auto associatedContext = Domain::Context::Ptr::create();
0138 
0139         auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0140         itemFetchJob->setItems(Akonadi::Item::List() << item);
0141         QTest::newRow("nominal case") << associatedContextItem << item << associatedContext << task << itemFetchJob << true;
0142 
0143         itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0144         itemFetchJob->setExpectedError(KJob::KilledJobError);
0145         QTest::newRow("task job error, cannot find task") << associatedContextItem << item << associatedContext << task << itemFetchJob << false;
0146     }
0147 
0148     void shouldAssociateATaskToAContext()
0149     {
0150         // GIVEN
0151         QFETCH(Akonadi::Item,associatedContextItem);
0152         QFETCH(Akonadi::Item,item);
0153         QFETCH(Domain::Context::Ptr,context);
0154         QFETCH(Domain::Task::Ptr,task);
0155         QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob);
0156         QFETCH(bool,execJob);
0157 
0158         // A mock update job
0159         auto itemModifyJob = new FakeJob(this);
0160 
0161         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0162         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0163         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0164                                                                                              serializerMock.getInstance()));
0165 
0166         // Storage mock returning the create job
0167         storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get())
0168                                                           .thenReturn(itemFetchJob);
0169         storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get())
0170                                                            .thenReturn(itemModifyJob);
0171 
0172         // Serializer mock returning the item for the task
0173         serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task)
0174                                                                          .thenReturn(item);
0175         serializerMock(&Akonadi::SerializerInterface::addContextToTask).when(context, item)
0176                                                                        .thenReturn();
0177 
0178         // WHEN
0179         auto associateJob = repository->associate(context, task);
0180         if (execJob)
0181             associateJob->exec();
0182 
0183         // THEN
0184         QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get()).exactly(1));
0185         if (execJob) {
0186             QVERIFY(serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task).exactly(1));
0187             QVERIFY(serializerMock(&Akonadi::SerializerInterface::addContextToTask).when(context, item).exactly(1));
0188             QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get()).exactly(1));
0189         }
0190     }
0191 
0192     void shoudDissociateTaskFromContext_data()
0193     {
0194         QTest::addColumn<Akonadi::Item>("item");
0195         QTest::addColumn<Domain::Context::Ptr>("context");
0196         QTest::addColumn<Domain::Task::Ptr>("task");
0197         QTest::addColumn<Testlib::AkonadiFakeItemFetchJob*>("itemFetchJob");
0198         QTest::addColumn<bool>("execJob");
0199 
0200         Akonadi::Item item(42);
0201         Domain::Task::Ptr task(new Domain::Task);
0202 
0203         auto associatedContext = Domain::Context::Ptr::create();
0204 
0205         auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0206         itemFetchJob->setItems(Akonadi::Item::List() << item);
0207         QTest::newRow("nominal case") << item << associatedContext << task << itemFetchJob << true;
0208 
0209         itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0210         itemFetchJob->setExpectedError(KJob::KilledJobError);
0211         QTest::newRow("task job error, cannot find task") << item << associatedContext << task << itemFetchJob << false;
0212     }
0213 
0214     void shoudDissociateTaskFromContext()
0215     {
0216         QFETCH(Akonadi::Item,item);
0217         QFETCH(Domain::Context::Ptr,context);
0218         QFETCH(Domain::Task::Ptr,task);
0219         QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob);
0220         QFETCH(bool,execJob);
0221 
0222         // A mock update job
0223         auto itemModifyJob = new FakeJob(this);
0224 
0225         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0226         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0227         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0228                                                                                              serializerMock.getInstance()));
0229 
0230         // Storage mock returning the create job
0231         storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get())
0232                                                           .thenReturn(itemFetchJob);
0233         storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get())
0234                                                            .thenReturn(itemModifyJob);
0235 
0236         // Serializer mock returning the item for the task
0237         serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task)
0238                                                                          .thenReturn(item);
0239         serializerMock(&Akonadi::SerializerInterface::removeContextFromTask).when(context, item)
0240                                                                             .thenReturn();
0241 
0242         // WHEN
0243         auto dissociateJob = repository->dissociate(context, task);
0244 
0245         if (execJob)
0246             dissociateJob->exec();
0247 
0248         // THEN
0249         QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get()).exactly(1));
0250         if (execJob) {
0251             QVERIFY(serializerMock(&Akonadi::SerializerInterface::removeContextFromTask).when(context, item).exactly(1));
0252             QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get()).exactly(1));
0253         }
0254     }
0255 
0256     void shouldDissociateTaskFromAllContext_data()
0257     {
0258         QTest::addColumn<Akonadi::Item>("item");
0259         QTest::addColumn<Domain::Task::Ptr>("task");
0260         QTest::addColumn<Testlib::AkonadiFakeItemFetchJob*>("itemFetchJob");
0261         QTest::addColumn<bool>("execJob");
0262 
0263         Akonadi::Item item(42);
0264         Domain::Task::Ptr task(new Domain::Task);
0265 
0266         auto itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0267         itemFetchJob->setItems(Akonadi::Item::List() << item);
0268         QTest::newRow("nominal case") << item << task << itemFetchJob << true;
0269 
0270         itemFetchJob = new Testlib::AkonadiFakeItemFetchJob(this);
0271         itemFetchJob->setExpectedError(KJob::KilledJobError);
0272         QTest::newRow("task job error, cannot find task") << item << task << itemFetchJob << false;
0273     }
0274 
0275     void shouldDissociateTaskFromAllContext()
0276     {
0277         QFETCH(Akonadi::Item,item);
0278         QFETCH(Domain::Task::Ptr,task);
0279         QFETCH(Testlib::AkonadiFakeItemFetchJob*,itemFetchJob);
0280         QFETCH(bool,execJob);
0281 
0282         // A mock update job
0283         auto itemModifyJob = new FakeJob(this);
0284 
0285         Utils::MockObject<Akonadi::StorageInterface> storageMock;
0286         Utils::MockObject<Akonadi::SerializerInterface> serializerMock;
0287         QScopedPointer<Akonadi::ContextRepository> repository(new Akonadi::ContextRepository(storageMock.getInstance(),
0288                                                                                              serializerMock.getInstance()));
0289 
0290         // Storage mock returning the create job
0291         storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get())
0292                                                           .thenReturn(itemFetchJob);
0293         storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get())
0294                                                            .thenReturn(itemModifyJob);
0295 
0296         // Serializer mock returning the item for the task
0297         serializerMock(&Akonadi::SerializerInterface::createItemFromTask).when(task)
0298                                                                          .thenReturn(item);
0299 
0300         // WHEN
0301         auto dissociateJob = repository->dissociateAll(task);
0302 
0303         if (execJob)
0304             dissociateJob->exec();
0305 
0306         // THEN
0307         QVERIFY(storageMock(&Akonadi::StorageInterface::fetchItem).when(item, repository.get()).exactly(1));
0308         if (execJob) {
0309             QVERIFY(storageMock(&Akonadi::StorageInterface::updateItem).when(item, repository.get()).exactly(1));
0310         } else {
0311             delete dissociateJob;
0312         }
0313 
0314         // Give a chance to itemFetchJob to delete itself
0315         // in case of an error (since it uses deleteLater() internally)
0316         QTest::qWait(10);
0317     }
0318 };
0319 
0320 ZANSHIN_TEST_MAIN(AkonadiContextRepositoryTest)
0321 
0322 #include "akonadicontextrepositorytest.moc"