#include #include #include #include "clientapi.h" #include "facade.h" #include "resourceconfig.h" #include "modelresult.h" #include "resultprovider.h" #include "facadefactory.h" template class DummyResourceFacade : public Akonadi2::StoreFacade { public: static std::shared_ptr > registerFacade(const QByteArray &instanceIdentifier = QByteArray()) { static QMap > > map; auto facade = std::make_shared >(); map.insert(instanceIdentifier, facade); bool alwaysReturnFacade = instanceIdentifier.isEmpty(); Akonadi2::FacadeFactory::instance().registerFacade >("dummyresource", [alwaysReturnFacade](const QByteArray &instanceIdentifier) { if (alwaysReturnFacade) { return map.value(QByteArray()); } return map.value(instanceIdentifier); } ); return facade; } ~DummyResourceFacade(){}; KAsync::Job create(const T &domainObject) Q_DECL_OVERRIDE { return KAsync::null(); }; KAsync::Job modify(const T &domainObject) Q_DECL_OVERRIDE { return KAsync::null(); }; KAsync::Job remove(const T &domainObject) Q_DECL_OVERRIDE { return KAsync::null(); }; QPair, typename Akonadi2::ResultEmitter::Ptr > load(const Akonadi2::Query &query) Q_DECL_OVERRIDE { auto resultProvider = new Akonadi2::ResultProvider(); resultProvider->onDone([resultProvider]() { Trace() << "Result provider is done"; delete resultProvider; }); //We have to do it this way, otherwise we're not setting the fetcher right auto emitter = resultProvider->emitter(); resultProvider->setFetcher([query, resultProvider, this](const typename T::Ptr &parent) { if (parent) { Trace() << "Running the fetcher " << parent->identifier(); } else { Trace() << "Running the fetcher."; } Trace() << "-------------------------."; for (const auto &res : results) { qDebug() << "Parent filter " << query.propertyFilter.value("parent").toByteArray() << res->identifier() << res->getProperty("parent").toByteArray(); auto parentProperty = res->getProperty("parent").toByteArray(); if ((!parent && parentProperty.isEmpty()) || (parent && parentProperty == parent->identifier()) || query.parentProperty.isEmpty()) { qDebug() << "Found a hit" << res->identifier(); resultProvider->add(res); } } resultProvider->initialResultSetComplete(parent); }); auto job = KAsync::start([query, resultProvider]() { }); mResultProvider = resultProvider; return qMakePair(job, emitter); } QList results; Akonadi2::ResultProviderInterface *mResultProvider; }; /** * Test of the client api implementation. * * This test works with injected dummy facades and thus doesn't write to storage. */ class ClientAPITest : public QObject { Q_OBJECT private Q_SLOTS: void initTestCase() { Akonadi2::FacadeFactory::instance().resetFactory(); ResourceConfig::clear(); Akonadi2::Log::setDebugOutputLevel(Akonadi2::Log::Trace); } void testLoad() { auto facade = DummyResourceFacade::registerFacade(); facade->results << QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Akonadi2::Query query; query.resources << "dummyresource.instance1"; query.liveQuery = false; auto model = Akonadi2::Store::loadModel(query); QTRY_VERIFY(model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()); QCOMPARE(model->rowCount(QModelIndex()), 1); } //TODO: This test doesn't belong to this testsuite void resourceManagement() { ResourceConfig::clear(); Akonadi2::FacadeFactory::instance().registerStaticFacades(); Akonadi2::ApplicationDomain::AkonadiResource res; res.setProperty("identifier", "dummyresource.identifier1"); res.setProperty("type", "dummyresource"); Akonadi2::Store::create(res).exec().waitForFinished(); { Akonadi2::Query query; query.propertyFilter.insert("type", "dummyresource"); auto model = Akonadi2::Store::loadModel(query); QTRY_COMPARE(model->rowCount(QModelIndex()), 1); } Akonadi2::Store::remove(res).exec().waitForFinished(); { Akonadi2::Query query; query.propertyFilter.insert("type", "dummyresource"); auto model = Akonadi2::Store::loadModel(query); QTRY_VERIFY(model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()); QCOMPARE(model->rowCount(QModelIndex()), 0); } } void testModelSingle() { auto facade = DummyResourceFacade::registerFacade(); facade->results << QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); Akonadi2::Query query; query.resources << "dummyresource.instance1"; query.liveQuery = false; auto model = Akonadi2::Store::loadModel(query); QTRY_COMPARE(model->rowCount(), 1); } void testModelNested() { auto facade = DummyResourceFacade::registerFacade(); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); subfolder->setProperty("parent", "id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); //Test Akonadi2::Query query; query.resources << "dummyresource.instance1"; query.liveQuery = false; query.parentProperty = "parent"; auto model = Akonadi2::Store::loadModel(query); QTRY_VERIFY(model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()); QCOMPARE(model->rowCount(), 1); model->fetchMore(model->index(0, 0)); QTRY_VERIFY(model->data(model->index(0, 0), Akonadi2::Store::ChildrenFetchedRole).toBool()); QCOMPARE(model->rowCount(model->index(0, 0)), 1); } void testModelSignals() { auto facade = DummyResourceFacade::registerFacade(); auto folder = QSharedPointer::create("resource", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("resource", "subId", 0, QSharedPointer::create()); subfolder->setProperty("parent", "id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); //Test Akonadi2::Query query; query.resources << "dummyresource.instance1"; query.liveQuery = false; query.parentProperty = "parent"; auto model = Akonadi2::Store::loadModel(query); QSignalSpy spy(model.data(), SIGNAL(rowsInserted(const QModelIndex &, int, int))); QVERIFY(spy.isValid()); model->fetchMore(model->index(0, 0)); QTRY_VERIFY(spy.count() >= 1); } void testModelNestedLive() { auto facade = DummyResourceFacade::registerFacade(); auto folder = QSharedPointer::create("dummyresource.instance1", "id", 0, QSharedPointer::create()); auto subfolder = QSharedPointer::create("dummyresource.instance1", "subId", 0, QSharedPointer::create()); subfolder->setProperty("parent", "id"); facade->results << folder << subfolder; ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); //Test Akonadi2::Query query; query.resources << "dummyresource.instance1"; query.liveQuery = true; query.parentProperty = "parent"; auto model = Akonadi2::Store::loadModel(query); QTRY_COMPARE(model->rowCount(), 1); model->fetchMore(model->index(0, 0)); QTRY_COMPARE(model->rowCount(model->index(0, 0)), 1); auto resultProvider = facade->mResultProvider; //Test new toplevel folder { QSignalSpy rowsInsertedSpy(model.data(), SIGNAL(rowsInserted(const QModelIndex &, int, int))); auto folder2 = QSharedPointer::create("resource", "id2", 0, QSharedPointer::create()); resultProvider->add(folder2); QTRY_COMPARE(model->rowCount(), 2); QTRY_COMPARE(rowsInsertedSpy.count(), 1); QCOMPARE(rowsInsertedSpy.at(0).at(0).value(), QModelIndex()); } //Test changed name { QSignalSpy dataChanged(model.data(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &, const QVector &))); folder->setProperty("subject", "modifiedSubject"); resultProvider->modify(folder); QTRY_COMPARE(model->rowCount(), 2); QTRY_COMPARE(dataChanged.count(), 1); } //Test removal { QSignalSpy rowsRemovedSpy(model.data(), SIGNAL(rowsRemoved(const QModelIndex &, int, int))); folder->setProperty("subject", "modifiedSubject"); resultProvider->remove(subfolder); QTRY_COMPARE(model->rowCount(model->index(0, 0)), 0); QTRY_COMPARE(rowsRemovedSpy.count(), 1); } //TODO: A modification can also be a move } void testLoadMultiResource() { auto facade1 = DummyResourceFacade::registerFacade("dummyresource.instance1"); facade1->results << QSharedPointer::create("resource1", "id", 0, QSharedPointer::create()); auto facade2 = DummyResourceFacade::registerFacade("dummyresource.instance2"); facade2->results << QSharedPointer::create("resource2", "id", 0, QSharedPointer::create()); ResourceConfig::addResource("dummyresource.instance1", "dummyresource"); ResourceConfig::addResource("dummyresource.instance2", "dummyresource"); Akonadi2::Query query; query.liveQuery = false; auto model = Akonadi2::Store::loadModel(query); QTRY_VERIFY(model->data(QModelIndex(), Akonadi2::Store::ChildrenFetchedRole).toBool()); QCOMPARE(model->rowCount(QModelIndex()), 2); } }; QTEST_MAIN(ClientAPITest) #include "clientapitest.moc"