diff --git a/src/akonadi/akonadicontextrepository.cpp b/src/akonadi/akonadicontextrepository.cpp index 3411d087..6546dffd 100644 --- a/src/akonadi/akonadicontextrepository.cpp +++ b/src/akonadi/akonadicontextrepository.cpp @@ -1,138 +1,138 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Franck Arrecot Copyright 2014 RĂ©mi Benoit This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadicontextrepository.h" #include "akonadiitemfetchjobinterface.h" #include "utils/compositejob.h" using namespace Akonadi; ContextRepository::ContextRepository(const StorageInterface::Ptr &storage, const SerializerInterface::Ptr &serializer): m_storage(storage), m_serializer(serializer) { } KJob *ContextRepository::create(Domain::Context::Ptr context) { auto tag = m_serializer->createTagFromContext(context); Q_ASSERT(!tag.isValid()); return m_storage->createTag(tag); } KJob *ContextRepository::update(Domain::Context::Ptr context) { auto tag = m_serializer->createTagFromContext(context); Q_ASSERT(tag.isValid()); return m_storage->updateTag(tag); } KJob *ContextRepository::remove(Domain::Context::Ptr context) { auto tag = m_serializer->createTagFromContext(context); Q_ASSERT(tag.isValid()); return m_storage->removeTag(tag); } KJob *ContextRepository::associate(Domain::Context::Ptr parent, Domain::Task::Ptr child) { Item childItem; childItem = m_serializer->createItemFromTask(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, parent, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); auto tag = m_serializer->createTagFromContext(parent); Q_ASSERT(tag.isValid()); childItem.setTag(tag); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *ContextRepository::dissociate(Domain::Context::Ptr parent, Domain::Task::Ptr child) { Item childItem; childItem = m_serializer->createItemFromTask(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, parent, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); auto tag = m_serializer->createTagFromContext(parent); Q_ASSERT(tag.isValid()); childItem.clearTag(tag); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *ContextRepository::dissociateAll(Domain::Task::Ptr child) { Item childItem; childItem = m_serializer->createItemFromTask(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); childItem.clearTags(); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } diff --git a/src/akonadi/akonadilivequeryhelpers.cpp b/src/akonadi/akonadilivequeryhelpers.cpp index 8856da6d..ff49a835 100644 --- a/src/akonadi/akonadilivequeryhelpers.cpp +++ b/src/akonadi/akonadilivequeryhelpers.cpp @@ -1,203 +1,203 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadilivequeryhelpers.h" #include "akonadi/akonadicollectionfetchjobinterface.h" #include "akonadi/akonadicollectionsearchjobinterface.h" #include "akonadi/akonadiitemfetchjobinterface.h" #include "akonadi/akonaditagfetchjobinterface.h" #include "utils/jobhandler.h" using namespace Akonadi; LiveQueryHelpers::LiveQueryHelpers(const SerializerInterface::Ptr &serializer, const StorageInterface::Ptr &storage) : m_serializer(serializer), m_storage(storage) { } LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::fetchAllCollections(StorageInterface::FetchContentTypes contentTypes) const { auto storage = m_storage; return [storage, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Collection::root(), StorageInterface::Recursive, contentTypes); Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error()) return; foreach (const auto &collection, job->collections()) add(collection); }); }; } LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::fetchCollections(const Collection &root, StorageInterface::FetchContentTypes contentTypes) const { auto storage = m_storage; return [storage, contentTypes, root] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(root, StorageInterface::Recursive, contentTypes); Utils::JobHandler::install(job->kjob(), [root, job, add] { if (job->kjob()->error()) return; auto directChildren = QHash(); foreach (const auto &collection, job->collections()) { auto directChild = collection; while (directChild.parentCollection() != root) directChild = directChild.parentCollection(); if (!directChildren.contains(directChild.id())) directChildren[directChild.id()] = directChild; } foreach (const auto &directChild, directChildren) add(directChild); }); }; } LiveQueryHelpers::CollectionFetchFunction LiveQueryHelpers::searchCollections(const Collection &root, const QString *searchTerm, StorageInterface::FetchContentTypes contentTypes) const { auto storage = m_storage; return [storage, contentTypes, searchTerm, root] (const Domain::LiveQueryInput::AddFunction &add) { if (searchTerm->isEmpty()) return; auto job = storage->searchCollections(*searchTerm, contentTypes); Utils::JobHandler::install(job->kjob(), [root, job, add] { if (job->kjob()->error()) return; auto directChildren = QHash(); foreach (const auto &collection, job->collections()) { auto directChild = collection; while (directChild.parentCollection() != root && directChild.parentCollection().isValid()) directChild = directChild.parentCollection(); if (directChild.parentCollection() != root) continue; if (!directChildren.contains(directChild.id())) directChildren[directChild.id()] = directChild; } foreach (const auto &directChild, directChildren) add(directChild); }); }; } LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchItems(StorageInterface::FetchContentTypes contentTypes) const { auto serializer = m_serializer; auto storage = m_storage; return [serializer, storage, contentTypes] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchCollections(Akonadi::Collection::root(), StorageInterface::Recursive, contentTypes); Utils::JobHandler::install(job->kjob(), [serializer, storage, job, add] { if (job->kjob()->error() != KJob::NoError) return; foreach (const auto &collection, job->collections()) { if (!serializer->isSelectedCollection(collection)) continue; auto job = storage->fetchItems(collection); Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; foreach (const auto &item, job->items()) add(item); }); } }); }; } LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchItems(const Tag &tag) const { // TODO: Qt5, use the proper implementation once we got a working akonadi #if 0 auto storage = m_storage; return [storage, tag] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTagItems(tag); Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; foreach (const auto &item, job->items()) add(item); }); }; #else auto fetchFunction = fetchItems(StorageInterface::Tasks | StorageInterface::Notes); return [tag, fetchFunction] (const Domain::LiveQueryInput::AddFunction &add) { auto filterAdd = [tag, add] (const Item &item) { if (item.tags().contains(tag)) add(item); }; fetchFunction(filterAdd); }; #endif } LiveQueryHelpers::ItemFetchFunction LiveQueryHelpers::fetchSiblings(const Item &item) const { auto storage = m_storage; return [storage, item] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchItem(item); Utils::JobHandler::install(job->kjob(), [storage, job, add] { if (job->kjob()->error() != KJob::NoError) return; Q_ASSERT(job->items().size() == 1); - auto item = job->items()[0]; + auto item = job->items().at(0); Q_ASSERT(item.parentCollection().isValid()); auto job = storage->fetchItems(item.parentCollection()); Utils::JobHandler::install(job->kjob(), [job, add] { if (job->kjob()->error() != KJob::NoError) return; foreach (const auto &item, job->items()) add(item); }); }); }; } LiveQueryHelpers::TagFetchFunction LiveQueryHelpers::fetchTags() const { auto storage = m_storage; return [storage] (const Domain::LiveQueryInput::AddFunction &add) { auto job = storage->fetchTags(); Utils::JobHandler::install(job->kjob(), [job, add] { foreach (const auto &tag, job->tags()) add(tag); }); }; } diff --git a/src/akonadi/akonadiprojectrepository.cpp b/src/akonadi/akonadiprojectrepository.cpp index c8fbef25..f2c7f468 100644 --- a/src/akonadi/akonadiprojectrepository.cpp +++ b/src/akonadi/akonadiprojectrepository.cpp @@ -1,149 +1,149 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadiprojectrepository.h" #include "akonadiitemfetchjobinterface.h" #include "utils/compositejob.h" using namespace Akonadi; ProjectRepository::ProjectRepository(const StorageInterface::Ptr &storage, const SerializerInterface::Ptr &serializer) : m_storage(storage), m_serializer(serializer) { } KJob *ProjectRepository::create(Domain::Project::Ptr project, Domain::DataSource::Ptr source) { auto item = m_serializer->createItemFromProject(project); Q_ASSERT(!item.isValid()); auto collection = m_serializer->createCollectionFromDataSource(source); Q_ASSERT(collection.isValid()); return m_storage->createItem(item, collection); } KJob *ProjectRepository::update(Domain::Project::Ptr project) { auto item = m_serializer->createItemFromProject(project); Q_ASSERT(item.isValid()); return m_storage->updateItem(item); } KJob *ProjectRepository::remove(Domain::Project::Ptr project) { auto item = m_serializer->createItemFromProject(project); Q_ASSERT(item.isValid()); return m_storage->removeItem(item); } KJob *ProjectRepository::associate(Domain::Project::Ptr parent, Domain::Artifact::Ptr child) { Item childItem; if (auto task = child.objectCast()) childItem = m_serializer->createItemFromTask(task); else if (auto note = child.objectCast()) childItem = m_serializer->createItemFromNote(note); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, parent, child, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); m_serializer->updateItemProject(childItem, parent); // Check collections to know if we need to move child auto parentItem = m_serializer->createItemFromProject(parent); ItemFetchJobInterface *fetchParentItemJob = m_storage->fetchItem(parentItem); job->install(fetchParentItemJob->kjob(), [fetchParentItemJob, child, childItem, job, this] { if (fetchParentItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchParentItemJob->items().size() == 1); - auto parentItem = fetchParentItemJob->items().first(); + auto parentItem = fetchParentItemJob->items().at(0); const int itemCollectionId = childItem.parentCollection().id(); const int parentCollectionId = parentItem.parentCollection().id(); if (child.objectCast() && itemCollectionId != parentCollectionId) { ItemFetchJobInterface *fetchChildrenItemJob = m_storage->fetchItems(childItem.parentCollection()); job->install(fetchChildrenItemJob->kjob(), [fetchChildrenItemJob, childItem, parentItem, job, this] { if (fetchChildrenItemJob->kjob()->error() != KJob::NoError) return; Item::List childItems = m_serializer->filterDescendantItems(fetchChildrenItemJob->items(), childItem); auto transaction = m_storage->createTransaction(); m_storage->updateItem(childItem, transaction); childItems.push_front(childItem); m_storage->moveItems(childItems, parentItem.parentCollection(), transaction); job->addSubjob(transaction); transaction->start(); }); } else { auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); } }); }); return job; } KJob *ProjectRepository::dissociate(Domain::Artifact::Ptr child) { auto job = new Utils::CompositeJob(); const auto task = child.objectCast(); const auto note = child.objectCast(); const auto childItem = task ? m_serializer->createItemFromTask(task) : note ? m_serializer->createItemFromNote(note) : Akonadi::Item(); Q_ASSERT(childItem.isValid()); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); m_serializer->removeItemParent(childItem); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } diff --git a/src/akonadi/akonaditagrepository.cpp b/src/akonadi/akonaditagrepository.cpp index d6446fba..cd86289a 100644 --- a/src/akonadi/akonaditagrepository.cpp +++ b/src/akonadi/akonaditagrepository.cpp @@ -1,128 +1,128 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens Copyright 2014 Franck Arrecot This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonaditagrepository.h" #include "akonadiitemfetchjobinterface.h" #include "utils/compositejob.h" using namespace Akonadi; TagRepository::TagRepository(const StorageInterface::Ptr &storage, const SerializerInterface::Ptr &serializer) : m_storage(storage), m_serializer(serializer) { } KJob *TagRepository::create(Domain::Tag::Ptr tag) { auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag); Q_ASSERT(!akonadiTag.isValid()); return m_storage->createTag(akonadiTag); } KJob *TagRepository::remove(Domain::Tag::Ptr tag) { auto akonadiTag = m_serializer->createAkonadiTagFromTag(tag); Q_ASSERT(akonadiTag.isValid()); return m_storage->removeTag(akonadiTag); } KJob *TagRepository::associate(Domain::Tag::Ptr parent, Domain::Note::Ptr child) { auto akonadiTag = m_serializer->createAkonadiTagFromTag(parent); Q_ASSERT(akonadiTag.isValid()); Item childItem = m_serializer->createItemFromNote(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [akonadiTag, fetchItemJob, parent, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); childItem.setTag(akonadiTag); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *TagRepository::dissociate(Domain::Tag::Ptr parent, Domain::Note::Ptr child) { Item childItem = m_serializer->createItemFromNote(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, parent, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); auto tag = m_serializer->createAkonadiTagFromTag(parent); Q_ASSERT(tag.isValid()); childItem.clearTag(tag); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *TagRepository::dissociateAll(Domain::Note::Ptr child) { Item childItem; childItem = m_serializer->createItemFromNote(child); Q_ASSERT(childItem.isValid()); auto job = new Utils::CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); foreach (const Tag &tag, childItem.tags()) childItem.clearTag(tag); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } diff --git a/src/akonadi/akonaditaskrepository.cpp b/src/akonadi/akonaditaskrepository.cpp index 1097a273..0231d01f 100644 --- a/src/akonadi/akonaditaskrepository.cpp +++ b/src/akonadi/akonaditaskrepository.cpp @@ -1,324 +1,324 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonaditaskrepository.h" #include #include "akonadicollectionfetchjobinterface.h" #include "akonadiitemfetchjobinterface.h" #include "utils/compositejob.h" using namespace Akonadi; using namespace Utils; TaskRepository::TaskRepository(const StorageInterface::Ptr &storage, const SerializerInterface::Ptr &serializer, const MessagingInterface::Ptr &messaging) : m_storage(storage), m_serializer(serializer), m_messaging(messaging) { } KJob *TaskRepository::createItem(const Item &item) { const Akonadi::Collection defaultCollection = m_storage->defaultTaskCollection(); if (defaultCollection.isValid()) { return m_storage->createItem(item, defaultCollection); } else { auto job = new CompositeJob(); CollectionFetchJobInterface *fetchCollectionJob = m_storage->fetchCollections(Akonadi::Collection::root(), StorageInterface::Recursive, StorageInterface::Tasks); job->install(fetchCollectionJob->kjob(), [fetchCollectionJob, item, job, this] { if (fetchCollectionJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchCollectionJob->collections().size() > 0); const Akonadi::Collection::List collections = fetchCollectionJob->collections(); auto it = std::find_if(collections.constBegin(), collections.constEnd(), [] (const Akonadi::Collection &c) { return (c.rights() & Akonadi::Collection::CanCreateItem) && (c.rights() & Akonadi::Collection::CanChangeItem) && (c.rights() & Akonadi::Collection::CanDeleteItem); }); if (it == collections.constEnd()) { job->emitError(tr("Could not find a collection to store the task into!")); } else { auto col = *it; Q_ASSERT(col.isValid()); auto createJob = m_storage->createItem(item, col); job->addSubjob(createJob); createJob->start(); } }); return job; } } KJob *TaskRepository::create(Domain::Task::Ptr task) { auto item = m_serializer->createItemFromTask(task); Q_ASSERT(!item.isValid()); return createItem(item); } KJob *TaskRepository::createChild(Domain::Task::Ptr task, Domain::Task::Ptr parent) { Item taskItem = m_serializer->createItemFromTask(task); Q_ASSERT(!taskItem.isValid()); Item parentItem = m_serializer->createItemFromTask(parent); Q_ASSERT(parentItem.isValid()); Q_ASSERT(parentItem.parentCollection().isValid()); m_serializer->updateItemParent(taskItem, parent); return m_storage->createItem(taskItem, parentItem.parentCollection()); } KJob *TaskRepository::createInProject(Domain::Task::Ptr task, Domain::Project::Ptr project) { Item taskItem = m_serializer->createItemFromTask(task); Q_ASSERT(!taskItem.isValid()); Item projectItem = m_serializer->createItemFromProject(project); Q_ASSERT(projectItem.isValid()); Q_ASSERT(projectItem.parentCollection().isValid()); m_serializer->updateItemProject(taskItem, project); return m_storage->createItem(taskItem, projectItem.parentCollection()); } KJob *TaskRepository::createInContext(Domain::Task::Ptr task, Domain::Context::Ptr context) { Item item = m_serializer->createItemFromTask(task); Q_ASSERT(!item.isValid()); Tag tag = m_serializer->createTagFromContext(context); Q_ASSERT(tag .isValid()); item.setTag(tag); return createItem(item); } KJob *TaskRepository::update(Domain::Task::Ptr task) { auto item = m_serializer->createItemFromTask(task); Q_ASSERT(item.isValid()); return m_storage->updateItem(item); } KJob *TaskRepository::remove(Domain::Task::Ptr task) { auto item = m_serializer->createItemFromTask(task); Q_ASSERT(item.isValid()); auto compositeJob = new CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(item); compositeJob->install(fetchItemJob->kjob(), [fetchItemJob, compositeJob, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto item = fetchItemJob->items().first(); + auto item = fetchItemJob->items().at(0); ItemFetchJobInterface *fetchCollectionItemsJob = m_storage->fetchItems(item.parentCollection()); compositeJob->install(fetchCollectionItemsJob->kjob(), [fetchCollectionItemsJob, item, compositeJob, this] { if (fetchCollectionItemsJob->kjob()->error() != KJob::NoError) return; Item::List childItems = m_serializer->filterDescendantItems(fetchCollectionItemsJob->items(), item); childItems << item; auto removeJob = m_storage->removeItems(childItems); compositeJob->addSubjob(removeJob); removeJob->start(); }); }); return compositeJob; } KJob *TaskRepository::promoteToProject(Domain::Task::Ptr task) { auto item = m_serializer->createItemFromTask(task); auto job = new CompositeJob(); auto fetchJob = m_storage->fetchItem(item); job->install(fetchJob->kjob(), [fetchJob, job, this] { if (fetchJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchJob->items().size() == 1); - auto item = fetchJob->items().first(); + auto item = fetchJob->items().at(0); m_serializer->promoteItemToProject(item); auto updateJob = m_storage->updateItem(item); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *TaskRepository::associate(Domain::Task::Ptr parent, Domain::Task::Ptr child) { auto childItem = m_serializer->createItemFromTask(child); auto job = new CompositeJob(); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, child, parent, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); m_serializer->updateItemParent(childItem, parent); // Check collections to know if we need to move child auto partialParentItem = m_serializer->createItemFromTask(parent); ItemFetchJobInterface *fetchParentItemJob = m_storage->fetchItems(partialParentItem.parentCollection()); job->install(fetchParentItemJob->kjob(), [child, parent, fetchParentItemJob, partialParentItem, childItem, job, this] { if (fetchParentItemJob->kjob()->error() != KJob::NoError) return; const auto items = fetchParentItemJob->items(); const auto parentIndex = items.indexOf(partialParentItem); Q_ASSERT(parentIndex >= 0); const auto parentItem = items.at(parentIndex); // TODO Qt5: This is a bit wasteful, add an itemUid on the serializer const auto childUid = m_serializer->objectUid(m_serializer->createTaskFromItem(childItem)); auto relatedUid = m_serializer->relatedUidFromItem(parentItem); while (!relatedUid.isEmpty()) { if (relatedUid == childUid) { job->emitError(tr("Could not associate '%1', it is an ancestor of '%2'") .arg(child->title(), parent->title())); return; } auto it = std::find_if(items.constBegin(), items.constEnd(), [relatedUid, this] (const Akonadi::Item &item) { // TODO Qt5: This is a bit wasteful, add an itemUid on the serializer auto task = m_serializer->createTaskFromItem(item); return task && m_serializer->objectUid(task) == relatedUid; }); if (it == items.end()) break; relatedUid = m_serializer->relatedUidFromItem(*it); } const int itemCollectionId = childItem.parentCollection().id(); const int parentCollectionId = parentItem.parentCollection().id(); if (itemCollectionId != parentCollectionId) { ItemFetchJobInterface *fetchChildrenItemJob = m_storage->fetchItems(childItem.parentCollection()); job->install(fetchChildrenItemJob->kjob(), [fetchChildrenItemJob, childItem, parentItem, job, this] { if (fetchChildrenItemJob->kjob()->error() != KJob::NoError) return; Item::List childItems = m_serializer->filterDescendantItems(fetchChildrenItemJob->items(), childItem); auto transaction = m_storage->createTransaction(); m_storage->updateItem(childItem, transaction); childItems.push_front(childItem); m_storage->moveItems(childItems, parentItem.parentCollection(), transaction); job->addSubjob(transaction); transaction->start(); }); } else { auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); } }); }); return job; } KJob *TaskRepository::dissociate(Domain::Task::Ptr child) { auto job = new CompositeJob(); auto childItem = m_serializer->createItemFromTask(child); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); m_serializer->removeItemParent(childItem); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *TaskRepository::dissociateAll(Domain::Task::Ptr child) { auto job = new CompositeJob(); auto childItem = m_serializer->createItemFromTask(child); ItemFetchJobInterface *fetchItemJob = m_storage->fetchItem(childItem); job->install(fetchItemJob->kjob(), [fetchItemJob, job, this] { if (fetchItemJob->kjob()->error() != KJob::NoError) return; Q_ASSERT(fetchItemJob->items().size() == 1); - auto childItem = fetchItemJob->items().first(); + auto childItem = fetchItemJob->items().at(0); m_serializer->removeItemParent(childItem); m_serializer->clearItem(&childItem); auto updateJob = m_storage->updateItem(childItem); job->addSubjob(updateJob); updateJob->start(); }); return job; } KJob *TaskRepository::delegate(Domain::Task::Ptr task, Domain::Task::Delegate delegate) { auto originalDelegate = task->delegate(); task->blockSignals(true); task->setDelegate(delegate); auto item = m_serializer->createItemFromTask(task); task->setDelegate(originalDelegate); task->blockSignals(false); m_messaging->sendDelegationMessage(item); return Q_NULLPTR; } diff --git a/tests/testlib/akonadistoragetestbase.cpp b/tests/testlib/akonadistoragetestbase.cpp index 72105a2a..efe30c93 100644 --- a/tests/testlib/akonadistoragetestbase.cpp +++ b/tests/testlib/akonadistoragetestbase.cpp @@ -1,1462 +1,1462 @@ /* This file is part of Zanshin Copyright 2014-2015 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "akonadistoragetestbase.h" #include #include #include #include #include #include #include #include "utils/mem_fn.h" #include "AkonadiCore/qtest_akonadi.h" #include #include "akonadi/akonadiapplicationselectedattribute.h" #include "akonadi/akonadicollectionfetchjobinterface.h" #include "akonadi/akonadicollectionsearchjobinterface.h" #include "akonadi/akonadiitemfetchjobinterface.h" #include "akonadi/akonadimonitorimpl.h" #include "akonadi/akonadistorage.h" #include "akonadi/akonadistoragesettings.h" #include "akonadi/akonaditagfetchjobinterface.h" #include "akonadi/akonaditimestampattribute.h" using namespace Testlib; AkonadiStorageTestBase::AkonadiStorageTestBase(QObject *parent) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } void AkonadiStorageTestBase::dumpTree() { TestLib::AkonadiDebug::dumpTree(createStorage()); } void AkonadiStorageTestBase::shouldListCollections_data() { QTest::addColumn("collection"); QTest::addColumn("expectedNames"); QTest::addColumn("depth"); QTest::addColumn("contentTypes"); QTest::addColumn("referenceCalendar1"); QTest::addColumn("enableCalendar1"); QTest::newRow("all") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("include referenced") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << true << false; QTest::newRow("include referenced + enabled") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << true << true; QTest::newRow("exclude !referenced + !enabled") << Akonadi::Collection::root() << QStringList({ "Calendar2", "Calendar3", "Change me!", "Destroy me!", "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes|Akonadi::StorageInterface::Tasks) << false << false; QTest::newRow("notes") << Akonadi::Collection::root() << QStringList({ "Notes" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Notes) << false << true; QTest::newRow("tasks") << Akonadi::Collection::root() << QStringList({ "Calendar1", "Calendar2", "Calendar3", "Change me!", "Destroy me!" }) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("base type") << calendar2() << QStringList({"Calendar2"}) << Akonadi::Storage::Base << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("firstLevel type") << calendar1() << QStringList({"Calendar2"}) << Akonadi::Storage::FirstLevel << int(Akonadi::StorageInterface::Tasks) << false << true; QTest::newRow("recursive type") << calendar1() << QStringList({"Calendar2", "Calendar3"}) << Akonadi::Storage::Recursive << int(Akonadi::StorageInterface::Tasks) << false << true; } void AkonadiStorageTestBase::shouldListCollections() { // GIVEN QFETCH(Akonadi::Collection, collection); QFETCH(QStringList, expectedNames); QFETCH(Akonadi::StorageInterface::FetchDepth, depth); QFETCH(int, contentTypes); QFETCH(bool, referenceCalendar1); QFETCH(bool, enableCalendar1); auto storage = createStorage(); // Default is not referenced and enabled // no need to feedle with the collection in that case if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(referenceCalendar1); cal1.setEnabled(enableCalendar1); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); } // WHEN auto job = storage->fetchCollections(collection, depth, Akonadi::StorageInterface::FetchContentTypes(contentTypes)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); QStringList collectionNames; for (const auto &collection : collections) { collectionNames << collection.name(); } collectionNames.sort(); // Restore proper DB state if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(false); cal1.setEnabled(true); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); } QCOMPARE(collectionNames, expectedNames); } void AkonadiStorageTestBase::shouldRetrieveAllCollectionAncestors() { // GIVEN auto storage = createStorage(); // WHEN auto job = storage->fetchCollections(Akonadi::Collection::root(), Akonadi::Storage::Recursive, Akonadi::Storage::Tasks|Akonadi::Storage::Notes); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); for (const auto &collection : collections) { auto parent = collection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); QVERIFY(!parent.displayName().isEmpty()); parent = parent.parentCollection(); } } } void AkonadiStorageTestBase::shouldListFullItemsInACollection() { // GIVEN auto storage = createStorage(); const QStringList expectedRemoteIds = { "{1d33862f-f274-4c67-ab6c-362d56521ff4}", "{1d33862f-f274-4c67-ab6c-362d56521ff5}", "{1d33862f-f274-4c67-ab6c-362d56521ff6}", "{7824df00-2fd6-47a4-8319-52659dc82005}", "{7824df00-2fd6-47a4-8319-52659dc82006}" }; // WHEN auto job = storage->fetchItems(calendar2()); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QStringList itemRemoteIds; for (const auto &item : items) { itemRemoteIds << item.remoteId(); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); Akonadi::Tag::List tags = item.tags(); QVERIFY(!item.tags().isEmpty()); for (const auto &tag : tags) { QVERIFY(tag.isValid()); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } itemRemoteIds.sort(); QCOMPARE(itemRemoteIds, expectedRemoteIds); } void AkonadiStorageTestBase::shouldListTags() { // GIVEN auto storage = createStorage(); const QStringList expectedGids = { "change-me", "delete-me", "errands-context", "online-context", "philosophy-tag", "physics-tag" }; // WHEN auto job = storage->fetchTags(); AKVERIFYEXEC(job->kjob()); // THEN auto tags = job->tags(); QStringList tagGids; for (const Akonadi::Tag &tag : tags) { tagGids << tag.gid(); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } tagGids.sort(); QCOMPARE(tagGids, expectedGids); } void AkonadiStorageTestBase::shouldListItemsAssociatedWithTag() { // GIVEN auto storage = createStorage(); Akonadi::Tag tag = fetchTagByGID(QStringLiteral("errands-context")); const QStringList expectedRemoteIds = { "{1d33862f-f274-4c67-ab6c-362d56521ff4}", "{7824df00-2fd6-47a4-8319-52659dc82005}" }; // WHEN auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QStringList itemRemoteIds; for (const auto &item : items) { itemRemoteIds << item.remoteId(); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } itemRemoteIds.sort(); QCOMPARE(itemRemoteIds, expectedRemoteIds); } void AkonadiStorageTestBase::shouldNotifyCollectionAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionAdded); MonitorSpy monitorSpy(monitor.data()); // A collection Akonadi::Collection collection; collection.setParentCollection(calendar2()); collection.setName(QStringLiteral("Foo!")); collection.setContentMimeTypes(QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo")); // WHEN auto storage = createStorage(); auto job = storage->createCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedCollection = spy.takeFirst().takeFirst().value(); + auto notifiedCollection = spy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.name(), collection.name()); auto parent = notifiedCollection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyCollectionRemoved() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) Akonadi::Collection collection = fetchCollectionByRID(QStringLiteral("{1f78b360-a01b-4785-9187-75450190342c}")); QVERIFY(collection.isValid()); // WHEN auto storage = createStorage(); auto job = storage->removeCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedCollection= spy.takeFirst().takeFirst().value(); + auto notifiedCollection= spy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); } void AkonadiStorageTestBase::shouldNotifyCollectionChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // A colection with an existing id (if we trust the test data) Akonadi::Collection collection = fetchCollectionByRID(QStringLiteral("{28ef9f03-4ebc-4e33-970f-f379775894f9}")); QVERIFY(collection.isValid()); collection.setName(QStringLiteral("Bar!")); // WHEN auto storage = createStorage(); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedCollection = spy.takeFirst().takeFirst().value(); + auto notifiedCollection = spy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QCOMPARE(notifiedCollection.name(), collection.name()); auto parent = notifiedCollection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(QStringLiteral("summary")); todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of an item... Akonadi::Item item; item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); item.addAttribute(new Akonadi::EntityDisplayAttribute); // WHEN auto storage = createStorage(); auto job = storage->createItem(item, calendar2()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(*notifiedItem.payload(), *todo); QVERIFY(notifiedItem.hasAttribute()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemRemoved() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); const Akonadi::Collection notesCol = fetchCollectionByRID(QStringLiteral("{f5e3f1be-b998-4c56-aa3d-e3a6e7e5493a}")); Akonadi::Item item = fetchItemByRID(QStringLiteral("{d0159c99-0d23-41fa-bb5f-436570140f8b}"), notesCol); QVERIFY(item.isValid()); // WHEN auto storage = createStorage(); auto job = storage->removeItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(QStringLiteral("summary")); todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of an existing item (if we trust the test data)... Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff6}"), calendar2()); QVERIFY(item.isValid()); item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); item.addAttribute(new Akonadi::EntityDisplayAttribute); // WHEN auto storage = createStorage(); auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); QCOMPARE(*notifiedItem.payload(), *todo); QVERIFY(notifiedItem.hasAttribute()); auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemTagAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data)... Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff5}"), calendar2()); QVERIFY(item.isValid()); item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); // An existing tag (if we trust the test data) Akonadi::Tag tag(5); // WHEN item.setTag(tag); auto storage = createStorage(); auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); QVERIFY(notifiedItem.hasPayload()); Akonadi::Tag::List notifiedTags = notifiedItem.tags(); QVERIFY(notifiedTags.contains(tag)); for (const auto &tag : notifiedTags) { QVERIFY(tag.isValid()); QVERIFY(!tag.name().isEmpty()); QVERIFY(!tag.type().isEmpty()); } auto parent = notifiedItem.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldNotifyItemTagRemoved() // aka dissociate { // GIVEN auto storage = createStorage(); Akonadi::Tag tag = fetchTagByGID(QStringLiteral("philosophy-tag")); const QString expectedRemoteIds = {QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82006}")}; auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); - auto item = job->items().first(); + auto item = job->items().at(0); QCOMPARE(item.remoteId(), expectedRemoteIds); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); QVERIFY(!item.tags().isEmpty()); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN item.clearTag(tag); auto jobUpdate = storage->updateItem(item); AKVERIFYEXEC(jobUpdate); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); QVERIFY(!notifiedItem.tags().contains(tag)); } void AkonadiStorageTestBase::shouldNotifyTagAdded() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); MonitorSpy monitorSpy(monitor.data()); // A tag Akonadi::Tag tag; tag.setGid("gid"); tag.setName(QStringLiteral("name")); tag.setType("type"); // WHEN auto storage = createStorage(); auto job = storage->createTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.gid(), tag.gid()); QCOMPARE(notifiedTag.name(), tag.name()); QCOMPARE(notifiedTag.type(), tag.type()); } void AkonadiStorageTestBase::shouldNotifyTagRemoved() { // GIVEN // An existing tag (if we trust the test data) connected to an existing item tagged to it auto storage = createStorage(); Akonadi::Tag tag = fetchTagByGID(QStringLiteral("delete-me")); // NOTE : this item was linked to the delete-me tag during test time const QString expectedRemoteIds = {QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff5}")}; auto job = storage->fetchTagItems(tag); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); - auto itemTagged = job->items().first(); + auto itemTagged = job->items().at(0); QCOMPARE(itemTagged.remoteId(), expectedRemoteIds); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); QSignalSpy spyItemChanged(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto jobDelete = storage->removeTag(tag); AKVERIFYEXEC(jobDelete); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); QTRY_VERIFY(!spyItemChanged.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.id(), tag.id()); QCOMPARE(spyItemChanged.size(), 1); - auto notifiedItem = spyItemChanged.takeFirst().takeFirst().value(); + auto notifiedItem = spyItemChanged.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), itemTagged.id()); } void AkonadiStorageTestBase::shouldNotifyTagChanged() { // GIVEN // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); MonitorSpy monitorSpy(monitor.data()); // An existing tag (if we trust the test data) Akonadi::Tag tag(6); tag.setName(QStringLiteral("Oh it changed!")); // WHEN auto storage = createStorage(); auto job = storage->updateTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.id(), tag.id()); QCOMPARE(notifiedTag.name(), tag.name()); } void AkonadiStorageTestBase::shouldReadDefaultNoteCollectionFromSettings() { // GIVEN // A storage implementation auto storage = createStorage(); // WHEN Akonadi::StorageSettings::instance().setDefaultNoteCollection(Akonadi::Collection(24)); // THEN QCOMPARE(storage->defaultNoteCollection(), Akonadi::Collection(24)); } void AkonadiStorageTestBase::shouldReadDefaultTaskCollectionFromSettings() { // GIVEN // A storage implementation auto storage = createStorage(); // WHEN Akonadi::StorageSettings::instance().setDefaultTaskCollection(Akonadi::Collection(24)); // THEN QCOMPARE(storage->defaultTaskCollection(), Akonadi::Collection(24)); } void AkonadiStorageTestBase::shouldUpdateItem() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(QStringLiteral("new summary")); todo->setDescription(QStringLiteral("new content")); // ... as payload of an existing item (if we trust the test data)... Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff4}"), calendar2()); item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN auto job = storage->updateItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); // KCalCore 4.83 fixes this bug #if KCALCORE_VERSION < 0x045300 QCOMPARE(notifiedItem.payload()->uid(), todo->uid()); QCOMPARE(notifiedItem.payload()->summary(), todo->summary()); QCOMPARE(notifiedItem.payload()->description(), todo->description()); QEXPECT_FAIL("", "Bug introduced by 76c686bc1de3a5d16956a627744ce352bc28d12a in KCalCore", Continue); QCOMPARE(*notifiedItem.payload(), *todo); QEXPECT_FAIL("", "Bug introduced by 76c686bc1de3a5d16956a627744ce352bc28d12a in KCalCore", Continue); QCOMPARE(notifiedItem.payload()->status(), todo->status()); #else QCOMPARE(*notifiedItem.payload(), *todo); #endif } void AkonadiStorageTestBase::shouldUseTransaction() { // GIVEN auto storage = createStorage(); Akonadi::Item item1 = fetchItemByRID(QStringLiteral("{0aa4dc30-a2c2-4e08-8241-033b3344debc}"), calendar1()); QVERIFY(item1.isValid()); Akonadi::Item item2 = fetchItemByRID(QStringLiteral("{5dc1aba7-eead-4254-ba7a-58e397de1179}"), calendar1()); QVERIFY(item2.isValid()); // create wrong item Akonadi::Item item3(10000); item3.setRemoteId(QStringLiteral("wrongId")); // A spied monitor auto monitor = createMonitor(); QSignalSpy spyUpdated(monitor.data(), &Akonadi::MonitorInterface::itemChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto todo = item1.payload(); todo->setSummary(QStringLiteral("Buy tomatoes")); todo = item2.payload(); todo->setSummary(QStringLiteral("Buy chocolate")); auto transaction = storage->createTransaction(); storage->updateItem(item1, transaction); storage->updateItem(item3, transaction); // this job should fail storage->updateItem(item2, transaction); QVERIFY(!transaction->exec()); monitorSpy.waitForStableState(); // THEN QCOMPARE(spyUpdated.size(), 0); auto job = storage->fetchItem(item1); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); - item1 = job->items()[0]; + item1 = job->items().at(0); job = storage->fetchItem(item2); AKVERIFYEXEC(job->kjob()); QCOMPARE(job->items().size(), 1); - item2 = job->items()[0]; + item2 = job->items().at(0); QCOMPARE(item1.payload()->summary(), QStringLiteral("Buy kiwis")); QCOMPARE(item2.payload()->summary(), QStringLiteral("Buy cheese")); } void AkonadiStorageTestBase::shouldCreateItem() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); MonitorSpy monitorSpy(monitor.data()); // A todo... KCalCore::Todo::Ptr todo(new KCalCore::Todo); todo->setSummary(QStringLiteral("summary")); todo->setDescription(QStringLiteral("content")); todo->setCompleted(false); todo->setDtStart(KDateTime(QDate(2013, 11, 24))); todo->setDtDue(KDateTime(QDate(2014, 03, 01))); // ... as payload of a new item Akonadi::Item item; item.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo")); item.setPayload(todo); // WHEN auto job = storage->createItem(item, calendar2()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.parentCollection(), calendar2()); QCOMPARE(*notifiedItem.payload(), *todo); } void AkonadiStorageTestBase::shouldRetrieveItem() { // GIVEN auto storage = createStorage(); Akonadi::Item findItem = fetchItemByRID(QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82005}"), calendar2()); QVERIFY(findItem.isValid()); // WHEN auto job = storage->fetchItem(findItem); AKVERIFYEXEC(job->kjob()); // THEN auto items = job->items(); QCOMPARE(items.size(), 1); const auto &item = items[0]; QCOMPARE(item.id(), findItem.id()); QVERIFY(item.loadedPayloadParts().contains(Akonadi::Item::FullPayload)); QVERIFY(!item.attributes().isEmpty()); QVERIFY(item.modificationTime().isValid()); QVERIFY(!item.flags().isEmpty()); auto parent = item.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); parent = parent.parentCollection(); } } void AkonadiStorageTestBase::shouldMoveItem() { // GIVEN auto storage = createStorage(); Akonadi::Item item = fetchItemByRID(QStringLiteral("{7824df00-2fd6-47a4-8319-52659dc82005}"), calendar2()); QVERIFY(item.isValid()); // A spied monitor auto monitor = createMonitor(); QSignalSpy spyMoved(monitor.data(), &Akonadi::MonitorInterface::itemMoved); MonitorSpy monitorSpy(monitor.data()); auto job = storage->moveItem(item, calendar1()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spyMoved.isEmpty()); QCOMPARE(spyMoved.size(), 1); - auto movedItem = spyMoved.takeFirst().takeFirst().value(); + auto movedItem = spyMoved.takeFirst().at(0).value(); QCOMPARE(movedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldMoveItems() { // GIVEN auto storage = createStorage(); Akonadi::Item item = fetchItemByRID(QStringLiteral("{1d33862f-f274-4c67-ab6c-362d56521ff4}"), calendar2()); QVERIFY(item.isValid()); Akonadi::Item::List list; list << item; // A spied monitor auto monitor = createMonitor(); QSignalSpy spyMoved(monitor.data(), &Akonadi::MonitorInterface::itemMoved); MonitorSpy monitorSpy(monitor.data()); auto job = storage->moveItems(list, calendar1()); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spyMoved.isEmpty()); QCOMPARE(spyMoved.size(), 1); - auto movedItem = spyMoved.takeFirst().takeFirst().value(); + auto movedItem = spyMoved.takeFirst().at(0).value(); QCOMPARE(movedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldDeleteItem() { //GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) Akonadi::Item item = fetchItemByRID(QStringLiteral("{0aa4dc30-a2c2-4e08-8241-033b3344debc}"), calendar1()); QVERIFY(item.isValid()); //When auto job = storage->removeItem(item); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); } void AkonadiStorageTestBase::shouldDeleteItems() { //GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing item (if we trust the test data) Akonadi::Item item = fetchItemByRID(QStringLiteral("{6c7bf5b9-4136-4203-9f45-54e32ea0eacb}"), calendar1()); QVERIFY(item.isValid()); Akonadi::Item item2 = fetchItemByRID(QStringLiteral("{83cf0b15-8d61-436b-97ae-4bd88fb2fef9}"), calendar1()); QVERIFY(item2.isValid()); Akonadi::Item::List list; list << item << item2; //When auto job = storage->removeItems(list); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 2); - auto notifiedItem = spy.takeFirst().takeFirst().value(); + auto notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item.id()); - notifiedItem = spy.takeFirst().takeFirst().value(); + notifiedItem = spy.takeFirst().at(0).value(); QCOMPARE(notifiedItem.id(), item2.id()); } void AkonadiStorageTestBase::shouldCreateTag() { // GIVEN // A storage implementation auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); MonitorSpy monitorSpy(monitor.data()); // A tag Akonadi::Tag tag; QString name = QStringLiteral("Tag42"); const QByteArray type = QByteArray("Zanshin-Context"); const QByteArray gid = QByteArray(name.toLatin1()); tag.setName(name); tag.setType(QByteArray("Zanshin-Context")); tag.setGid(gid); // WHEN auto job = storage->createTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.name(), name); QCOMPARE(notifiedTag.type(), type); QCOMPARE(notifiedTag.gid(), gid); } void AkonadiStorageTestBase::shouldRemoveTag() { // GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); MonitorSpy monitorSpy(monitor.data()); // An existing tag Akonadi::Tag tag = fetchTagByGID(QStringLiteral("errands-context")); // WHEN auto job = storage->removeTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.id(), tag.id()); } void AkonadiStorageTestBase::shouldUpdateTag() { // GIVEN auto storage = createStorage(); // A spied monitor auto monitor = createMonitor(); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); MonitorSpy monitorSpy(monitor.data()); // An existing tag Akonadi::Tag tag = fetchTagByGID(QStringLiteral("change-me")); // WHEN auto job = storage->updateTag(tag); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!spy.isEmpty()); // THEN QCOMPARE(spy.size(), 1); - auto notifiedTag = spy.takeFirst().takeFirst().value(); + auto notifiedTag = spy.takeFirst().at(0).value(); QCOMPARE(notifiedTag.id(), tag.id()); } void AkonadiStorageTestBase::shouldUpdateCollection() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::EntityDisplayAttribute; attr->setDisplayName(QStringLiteral("Foo")); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QCOMPARE(selectionSpy.size(), 0); - auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); + auto notifiedCollection = changeSpy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QCOMPARE(notifiedCollection.attribute()->displayName(), attr->displayName()); } void AkonadiStorageTestBase::shouldNotifyCollectionTimestampChanges() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN collection.attribute(Akonadi::Collection::AddIfMissing)->refreshTimestamp(); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); - auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); + auto notifiedCollection = changeSpy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); } void AkonadiStorageTestBase::shouldNotifyCollectionSelectionChanges() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = calendar2(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::ApplicationSelectedAttribute; attr->setSelected(false); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QCOMPARE(selectionSpy.size(), 1); - auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); + auto notifiedCollection = changeSpy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QVERIFY(!notifiedCollection.attribute()->isSelected()); - notifiedCollection = selectionSpy.takeFirst().takeFirst().value(); + notifiedCollection = selectionSpy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QVERIFY(notifiedCollection.hasAttribute()); QVERIFY(!notifiedCollection.attribute()->isSelected()); } void AkonadiStorageTestBase::shouldNotNotifyCollectionSelectionChangesForIrrelevantCollections() { // GIVEN // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection = emails(); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); QSignalSpy selectionSpy(monitor.data(), &Akonadi::MonitorInterface::collectionSelectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN auto attr = new Akonadi::ApplicationSelectedAttribute; attr->setSelected(false); collection.addAttribute(attr); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); QVERIFY(selectionSpy.isEmpty()); } void AkonadiStorageTestBase::shouldNotifyCollectionSubscriptionChanges_data() { QTest::addColumn("isEnabled"); QTest::addColumn("isReferenced"); QTest::newRow("enabled and !referenced") << true << false; // Fails randomly due to an akonadi bug... //QTest::newRow("!enabled and referenced") << false << true; QTest::newRow("!enabled and !referenced") << false << false; QTest::newRow("!enabled and referenced (again)") << false << true; QTest::newRow("enabled and !referenced (again)") << true << false; } void AkonadiStorageTestBase::shouldNotifyCollectionSubscriptionChanges() { // GIVEN QFETCH(bool, isEnabled); QFETCH(bool, isReferenced); // A storage implementation auto storage = createStorage(); // An existing collection Akonadi::Collection collection(calendar2().id()); // A spied monitor auto monitor = createMonitor(); QSignalSpy changeSpy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); MonitorSpy monitorSpy(monitor.data()); // WHEN static int run = 1; collection.attribute(Akonadi::Collection::AddIfMissing) ->setIconName(QStringLiteral("folder-%1").arg(run++)); collection.setEnabled(isEnabled); collection.setReferenced(isReferenced); auto job = storage->updateCollection(collection); AKVERIFYEXEC(job); monitorSpy.waitForStableState(); QTRY_VERIFY(!changeSpy.isEmpty()); // THEN QCOMPARE(changeSpy.size(), 1); - auto notifiedCollection = changeSpy.takeFirst().takeFirst().value(); + auto notifiedCollection = changeSpy.takeFirst().at(0).value(); QCOMPARE(notifiedCollection.id(), collection.id()); QCOMPARE(notifiedCollection.enabled(), isEnabled); QCOMPARE(notifiedCollection.referenced(), isReferenced); } void AkonadiStorageTestBase::shouldFindCollectionsByName_data() { QTest::addColumn("name"); QTest::addColumn("contentType"); QTest::addColumn("expectedResults"); QTest::addColumn("referenceCalendar1"); QTest::addColumn("enableCalendar1"); QStringList expectedResults; expectedResults << QStringLiteral("Calendar1"); QTest::newRow("get a collection") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); QTest::newRow("try with wrong type") << "Calendar1" << int(Akonadi::StorageInterface::Notes) << expectedResults << false << true; expectedResults << QStringLiteral("Notes"); QTest::newRow("get a note collection") << "Not" << int(Akonadi::StorageInterface::Notes) << expectedResults << false << true; expectedResults.clear(); QTest::newRow("try with unknown name") << "toto" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults << QStringLiteral("Calendar3") << QStringLiteral("Calendar2") << QStringLiteral("Calendar1"); QTest::newRow("try with a part of a name") << "Calendar" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); expectedResults << QStringLiteral("Calendar2"); QTest::newRow("make sure it is case insensitive") << "calendar2" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << true; expectedResults.clear(); expectedResults << QStringLiteral("Calendar1"); QTest::newRow("include referenced") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << true << false; QTest::newRow("include referenced + enabled") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << true << true; QTest::newRow("include !referenced + !enabled") << "Calendar1" << int(Akonadi::StorageInterface::Tasks) << expectedResults << false << false; } void AkonadiStorageTestBase::shouldFindCollectionsByName() { // GIVEN auto storage = createStorage(); QFETCH(QString, name); QFETCH(int, contentType); QFETCH(QStringList, expectedResults); QFETCH(bool, referenceCalendar1); QFETCH(bool, enableCalendar1); // A spied monitor auto monitor = createMonitor(); MonitorSpy monitorSpy(monitor.data()); // Default is not referenced and enabled // no need to feedle with the collection in that case if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(referenceCalendar1); cal1.setEnabled(enableCalendar1); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); monitorSpy.waitForStableState(); } // WHEN auto job = storage->searchCollections(name, Akonadi::StorageInterface::FetchContentType(contentType)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); // Restore proper DB state if (referenceCalendar1 || !enableCalendar1) { Akonadi::Collection cal1 = calendar1(); cal1.setReferenced(false); cal1.setEnabled(true); auto update = storage->updateCollection(cal1); AKVERIFYEXEC(update); monitorSpy.waitForStableState(); } auto collectionNames = QStringList(); std::transform(collections.constBegin(), collections.constEnd(), std::back_inserter(collectionNames), Utils::mem_fn(&Akonadi::Collection::name)); QCOMPARE(collectionNames.toSet(), expectedResults.toSet()); } void AkonadiStorageTestBase::shouldFindCollectionsByNameIncludingTheirAncestors_data() { QTest::addColumn("searchTerm"); QTest::addColumn("contentType"); QTest::newRow("task search") << "Calendar3" << int(Akonadi::StorageInterface::Tasks); QTest::newRow("note search") << "Notes" << int(Akonadi::StorageInterface::Notes); } void AkonadiStorageTestBase::shouldFindCollectionsByNameIncludingTheirAncestors() { // GIVEN auto storage = createStorage(); // WHEN QFETCH(QString, searchTerm); QFETCH(int, contentType); auto job = storage->searchCollections(searchTerm, Akonadi::StorageInterface::FetchContentType(contentType)); AKVERIFYEXEC(job->kjob()); // THEN auto collections = job->collections(); for (const auto &collection : collections) { auto parent = collection.parentCollection(); while (parent != Akonadi::Collection::root()) { QVERIFY(parent.isValid()); QVERIFY(!parent.displayName().isEmpty()); parent = parent.parentCollection(); } } } Akonadi::Item AkonadiStorageTestBase::fetchItemByRID(const QString &remoteId, const Akonadi::Collection &collection) { Akonadi::Item item; item.setRemoteId(remoteId); auto job = createStorage()->fetchItem(item); job->setCollection(collection); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString(); return Akonadi::Item(); } if (job->items().count() != 1) { qWarning() << "Received unexpected amount of items: " << job->items().count(); return Akonadi::Item(); } - return job->items().first(); + return job->items().at(0); } Akonadi::Collection AkonadiStorageTestBase::fetchCollectionByRID(const QString &remoteId) { Akonadi::Collection collection; collection.setRemoteId(remoteId); auto job = createStorage()->fetchCollections(collection, Akonadi::StorageInterface::Base, Akonadi::StorageInterface::AllContent); job->setResource(QStringLiteral("akonadi_knut_resource_0")); job->setFiltered(false); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString() << remoteId; return Akonadi::Collection(); } if (job->collections().count() != 1) { qWarning() << "Received unexpected amount of collections: " << job->collections().count(); return Akonadi::Collection(); } - return job->collections().first(); + return job->collections().at(0); } Akonadi::Tag AkonadiStorageTestBase::fetchTagByGID(const QString &gid) { auto job = createStorage()->fetchTags(); if (!job->kjob()->exec()) { qWarning() << job->kjob()->errorString(); return Akonadi::Tag(); } auto tags = job->tags(); for (const Akonadi::Tag &tag : tags) { if (tag.gid() == gid) return tag; } return Akonadi::Tag(); } Akonadi::Collection AkonadiStorageTestBase::calendar1() { return fetchCollectionByRID(QStringLiteral("{cdc229c7-a9b5-4d37-989d-a28e372be2a9}")); } Akonadi::Collection AkonadiStorageTestBase::calendar2() { return fetchCollectionByRID(QStringLiteral("{e682b8b5-b67c-4538-8689-6166f64177f0}")); } Akonadi::Collection AkonadiStorageTestBase::emails() { return fetchCollectionByRID(QStringLiteral("{14096930-7bfe-46ca-8fba-7c04d3b62ec8}")); } diff --git a/tests/units/presentation/applicationmodeltest.cpp b/tests/units/presentation/applicationmodeltest.cpp index f8aa45ec..8faf4cde 100644 --- a/tests/units/presentation/applicationmodeltest.cpp +++ b/tests/units/presentation/applicationmodeltest.cpp @@ -1,252 +1,252 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/dependencymanager.h" #include "utils/jobhandler.h" #include "utils/mockobject.h" #include "presentation/applicationmodel.h" #include "presentation/artifacteditormodel.h" #include "presentation/availablepagesmodelinterface.h" #include "presentation/availablesourcesmodel.h" #include "presentation/pagemodel.h" #include "presentation/errorhandler.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class FakeAvailablePagesModel : public Presentation::AvailablePagesModelInterface { Q_OBJECT public: explicit FakeAvailablePagesModel(QObject *parent = Q_NULLPTR) : Presentation::AvailablePagesModelInterface(parent) {} QAbstractItemModel *pageListModel() Q_DECL_OVERRIDE { return Q_NULLPTR; } bool hasProjectPages() const Q_DECL_OVERRIDE { return false; } bool hasContextPages() const Q_DECL_OVERRIDE { return false; } bool hasTagPages() const Q_DECL_OVERRIDE { return false; } QObject *createPageForIndex(const QModelIndex &) Q_DECL_OVERRIDE { return Q_NULLPTR; } void addProject(const QString &, const Domain::DataSource::Ptr &) Q_DECL_OVERRIDE {} void addContext(const QString &) Q_DECL_OVERRIDE {} void addTag(const QString &) Q_DECL_OVERRIDE {} void removeItem(const QModelIndex &) Q_DECL_OVERRIDE {} }; class FakePageModel : public Presentation::PageModel { Q_OBJECT public: explicit FakePageModel(QObject *parent = Q_NULLPTR) : Presentation::PageModel(parent) {} Domain::Artifact::Ptr addItem(const QString &, const QModelIndex &) Q_DECL_OVERRIDE { return {}; } void removeItem(const QModelIndex &) Q_DECL_OVERRIDE {} void promoteItem(const QModelIndex &) Q_DECL_OVERRIDE {} private: QAbstractItemModel *createCentralListModel() Q_DECL_OVERRIDE { return {}; } }; class ApplicationModelTest : public QObject { Q_OBJECT public: explicit ApplicationModelTest(QObject *parent = Q_NULLPTR) : QObject(parent) { Utils::DependencyManager::globalInstance().add(); Utils::DependencyManager::globalInstance().add( [] (Utils::DependencyManager *) { return new Presentation::ArtifactEditorModel; }); Utils::DependencyManager::globalInstance().add( [] (Utils::DependencyManager *) { return new Presentation::AvailableSourcesModel(Domain::DataSourceQueries::Ptr(), Domain::DataSourceRepository::Ptr()); }); } private slots: void shouldProvideAvailableSourcesModel() { // GIVEN Presentation::ApplicationModel app; // WHEN QObject *available = app.availableSources(); // THEN QVERIFY(qobject_cast(available)); } void shouldProvideAvailablePagesModel() { // GIVEN Presentation::ApplicationModel app; // WHEN QObject *available = app.availablePages(); // THEN QVERIFY(qobject_cast(available)); } void shouldProvideCurrentPage() { // GIVEN Presentation::ApplicationModel app; QVERIFY(!app.currentPage()); QSignalSpy spy(&app, &Presentation::ApplicationModel::currentPageChanged); // WHEN auto page = new FakePageModel(this); app.setCurrentPage(page); // THEN QCOMPARE(app.currentPage(), page); QCOMPARE(spy.count(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), page); + QCOMPARE(spy.takeFirst().at(0).value(), page); } void shouldSupportNullPage() { // GIVEN Presentation::ApplicationModel app; auto page = new FakePageModel(this); app.setCurrentPage(page); QCOMPARE(app.currentPage(), page); QSignalSpy spy(&app, &Presentation::ApplicationModel::currentPageChanged); // WHEN app.setCurrentPage(Q_NULLPTR); // THEN QVERIFY(!app.currentPage()); QCOMPARE(spy.count(), 1); - QVERIFY(!spy.takeFirst().takeFirst().value()); + QVERIFY(!spy.takeFirst().at(0).value()); } void shouldTakeOwnershipOfCurrentPage() { // GIVEN auto page = QPointer(new FakePageModel(this)); { Presentation::ApplicationModel app; // WHEN app.setCurrentPage(page.data()); // THEN QVERIFY(!page->parent()); QCOMPARE(app.currentPage(), page.data()); } // We don't crash and page is deleted QVERIFY(!page); } void shouldProvideArtifactEditorModel() { // GIVEN Presentation::ApplicationModel app; // WHEN QObject *page = app.editor(); // THEN QVERIFY(qobject_cast(page)); } void shouldSetErrorHandlerToAllModels() { // GIVEN // An ErrorHandler FakeErrorHandler errorHandler; Presentation::ApplicationModel app; app.setCurrentPage(new FakePageModel); // WHEN app.setErrorHandler(&errorHandler); // THEN auto availableSource = static_cast(app.availableSources()); auto availablePages = static_cast(app.availablePages()); auto editor = static_cast(app.editor()); auto page = static_cast(app.currentPage()); QCOMPARE(availableSource->errorHandler(), &errorHandler); QCOMPARE(availablePages->errorHandler(), &errorHandler); QCOMPARE(editor->errorHandler(), &errorHandler); QCOMPARE(page->errorHandler(), &errorHandler); // WHEN FakeErrorHandler errorHandler2; app.setErrorHandler(&errorHandler2); // THEN QCOMPARE(availableSource->errorHandler(), &errorHandler2); QCOMPARE(availablePages->errorHandler(), &errorHandler2); QCOMPARE(editor->errorHandler(), &errorHandler2); QCOMPARE(page->errorHandler(), &errorHandler2); } void shouldClearJobHandlersOnExit() { // GIVEN auto app = new Presentation::ApplicationModel; Utils::JobHandler::install(new FakeJob, [] { qFatal("Shouldn't happen"); }); QCOMPARE(Utils::JobHandler::jobCount(), 1); // WHEN delete app; // THEN QCOMPARE(Utils::JobHandler::jobCount(), 0); QTest::qWait(FakeJob::DURATION * 2); } }; ZANSHIN_TEST_MAIN(ApplicationModelTest) #include "applicationmodeltest.moc" diff --git a/tests/units/presentation/artifacteditormodeltest.cpp b/tests/units/presentation/artifacteditormodeltest.cpp index bce25ffb..19e2c5fb 100644 --- a/tests/units/presentation/artifacteditormodeltest.cpp +++ b/tests/units/presentation/artifacteditormodeltest.cpp @@ -1,459 +1,459 @@ /* This file is part of Zanshin Copyright 2014 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "utils/mockobject.h" #include #include "testlib/fakejob.h" #include "domain/task.h" #include "domain/note.h" #include "presentation/artifacteditormodel.h" #include "presentation/errorhandler.h" using namespace mockitopp; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) { m_message = message; } QString m_message; }; class ArtifactEditorModelTest : public QObject { Q_OBJECT private slots: void shouldHaveEmptyDefaultState() { // GIVEN Presentation::ArtifactEditorModel model; // WHEN // Nothing // THEN QVERIFY(model.artifact().isNull()); QVERIFY(!model.hasTaskProperties()); QVERIFY(model.text().isEmpty()); QVERIFY(model.title().isEmpty()); QVERIFY(!model.isDone()); QVERIFY(model.startDate().isNull()); QVERIFY(model.dueDate().isNull()); QVERIFY(model.delegateText().isNull()); QVERIFY(!model.hasSaveFunction()); QVERIFY(!model.hasDelegateFunction()); } void shouldHaveTaskProperties() { // GIVEN Presentation::ArtifactEditorModel model; QSignalSpy textSpy(&model, &Presentation::ArtifactEditorModel::textChanged); QSignalSpy titleSpy(&model, &Presentation::ArtifactEditorModel::titleChanged); QSignalSpy doneSpy(&model, &Presentation::ArtifactEditorModel::doneChanged); QSignalSpy startSpy(&model, &Presentation::ArtifactEditorModel::startDateChanged); QSignalSpy dueSpy(&model, &Presentation::ArtifactEditorModel::dueDateChanged); QSignalSpy delegateSpy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); auto task = Domain::Task::Ptr::create(); task->setText(QStringLiteral("description")); task->setTitle(QStringLiteral("title")); task->setDone(true); task->setStartDate(QDateTime::currentDateTime()); task->setDueDate(QDateTime::currentDateTime().addDays(2)); task->setDelegate(Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com"))); // WHEN model.setArtifact(task); // To make sure we don't signal too much model.setText(task->text()); model.setTitle(task->title()); model.setDone(task->isDone()); model.setStartDate(task->startDate()); model.setDueDate(task->dueDate()); // THEN QVERIFY(model.hasTaskProperties()); QCOMPARE(textSpy.size(), 1); - QCOMPARE(textSpy.takeFirst().takeFirst().toString(), task->text()); + QCOMPARE(textSpy.takeFirst().at(0).toString(), task->text()); QCOMPARE(model.property("text").toString(), task->text()); QCOMPARE(titleSpy.size(), 1); - QCOMPARE(titleSpy.takeFirst().takeFirst().toString(), task->title()); + QCOMPARE(titleSpy.takeFirst().at(0).toString(), task->title()); QCOMPARE(model.property("title").toString(), task->title()); QCOMPARE(doneSpy.size(), 1); - QCOMPARE(doneSpy.takeFirst().takeFirst().toBool(), task->isDone()); + QCOMPARE(doneSpy.takeFirst().at(0).toBool(), task->isDone()); QCOMPARE(model.property("done").toBool(), task->isDone()); QCOMPARE(startSpy.size(), 1); - QCOMPARE(startSpy.takeFirst().takeFirst().toDateTime(), task->startDate()); + QCOMPARE(startSpy.takeFirst().at(0).toDateTime(), task->startDate()); QCOMPARE(model.property("startDate").toDateTime(), task->startDate()); QCOMPARE(dueSpy.size(), 1); - QCOMPARE(dueSpy.takeFirst().takeFirst().toDateTime(), task->dueDate()); + QCOMPARE(dueSpy.takeFirst().at(0).toDateTime(), task->dueDate()); QCOMPARE(model.property("dueDate").toDateTime(), task->dueDate()); QCOMPARE(delegateSpy.size(), 1); - QCOMPARE(delegateSpy.takeFirst().takeFirst().toString(), task->delegate().display()); + QCOMPARE(delegateSpy.takeFirst().at(0).toString(), task->delegate().display()); QCOMPARE(model.property("delegateText").toString(), task->delegate().display()); } void shouldHaveNoteProperties() { // GIVEN Presentation::ArtifactEditorModel model; QSignalSpy textSpy(&model, &Presentation::ArtifactEditorModel::textChanged); QSignalSpy titleSpy(&model, &Presentation::ArtifactEditorModel::titleChanged); QSignalSpy doneSpy(&model, &Presentation::ArtifactEditorModel::doneChanged); QSignalSpy startSpy(&model, &Presentation::ArtifactEditorModel::startDateChanged); QSignalSpy dueSpy(&model, &Presentation::ArtifactEditorModel::dueDateChanged); QSignalSpy delegateSpy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); auto note = Domain::Note::Ptr::create(); note->setText(QStringLiteral("description")); note->setTitle(QStringLiteral("title")); // WHEN model.setArtifact(note); // To make sure we don't signal too much model.setText(note->text()); model.setTitle(note->title()); // THEN QVERIFY(!model.hasTaskProperties()); QCOMPARE(textSpy.size(), 1); - QCOMPARE(textSpy.takeFirst().takeFirst().toString(), note->text()); + QCOMPARE(textSpy.takeFirst().at(0).toString(), note->text()); QCOMPARE(model.property("text").toString(), note->text()); QCOMPARE(titleSpy.size(), 1); - QCOMPARE(titleSpy.takeFirst().takeFirst().toString(), note->title()); + QCOMPARE(titleSpy.takeFirst().at(0).toString(), note->title()); QCOMPARE(model.property("title").toString(), note->title()); QCOMPARE(doneSpy.size(), 1); - QCOMPARE(doneSpy.takeFirst().takeFirst().toBool(), false); + QCOMPARE(doneSpy.takeFirst().at(0).toBool(), false); QCOMPARE(model.property("done").toBool(), false); QCOMPARE(startSpy.size(), 1); - QVERIFY(startSpy.takeFirst().takeFirst().toDateTime().isNull()); + QVERIFY(startSpy.takeFirst().at(0).toDateTime().isNull()); QVERIFY(model.property("startDate").toDateTime().isNull()); QCOMPARE(dueSpy.size(), 1); - QVERIFY(dueSpy.takeFirst().takeFirst().toDateTime().isNull()); + QVERIFY(dueSpy.takeFirst().at(0).toDateTime().isNull()); QVERIFY(model.property("dueDate").toDateTime().isNull()); QCOMPARE(delegateSpy.size(), 1); - QVERIFY(delegateSpy.takeFirst().takeFirst().toString().isEmpty()); + QVERIFY(delegateSpy.takeFirst().at(0).toString().isEmpty()); QVERIFY(model.property("delegateText").toString().isEmpty()); } void shouldReactToArtifactPropertyChanges_data() { QTest::addColumn("artifact"); QTest::addColumn("propertyName"); QTest::addColumn("propertyValue"); QTest::addColumn("signal"); QTest::newRow("note text") << Domain::Artifact::Ptr(Domain::Note::Ptr::create()) << QByteArray("text") << QVariant("new text") << QByteArray(SIGNAL(textChanged(QString))); QTest::newRow("note title") << Domain::Artifact::Ptr(Domain::Note::Ptr::create()) << QByteArray("title") << QVariant("new title") << QByteArray(SIGNAL(titleChanged(QString))); QTest::newRow("task text") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("text") << QVariant("new text") << QByteArray(SIGNAL(textChanged(QString))); QTest::newRow("task title") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("title") << QVariant("new title") << QByteArray(SIGNAL(titleChanged(QString))); QTest::newRow("task done") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("done") << QVariant(true) << QByteArray(SIGNAL(doneChanged(bool))); QTest::newRow("task start") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("startDate") << QVariant(QDateTime::currentDateTime()) << QByteArray(SIGNAL(startDateChanged(QDateTime))); QTest::newRow("task due") << Domain::Artifact::Ptr(Domain::Task::Ptr::create()) << QByteArray("dueDate") << QVariant(QDateTime::currentDateTime().addDays(2)) << QByteArray(SIGNAL(dueDateChanged(QDateTime))); } void shouldReactToArtifactPropertyChanges() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); Presentation::ArtifactEditorModel model; model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN artifact->setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); + QCOMPARE(spy.takeFirst().at(0), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); } void shouldReactToTaskDelegateChanges() { // GIVEN auto task = Domain::Task::Ptr::create(); Presentation::ArtifactEditorModel model; model.setArtifact(task); QSignalSpy spy(&model, &Presentation::ArtifactEditorModel::delegateTextChanged); // WHEN task->setDelegate(Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com"))); // THEN QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().toString(), task->delegate().display()); + QCOMPARE(spy.takeFirst().at(0).toString(), task->delegate().display()); QCOMPARE(model.property("delegateText").toString(), task->delegate().display()); } void shouldApplyChangesBackToArtifactAfterADelay_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesBackToArtifactAfterADelay() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setSaveFunction(save); model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN model.setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); + QCOMPARE(spy.takeFirst().at(0), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply after delay) QTest::qWait(model.autoSaveDelay() + 50); // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldApplyChangesImmediatelyIfANewArtifactIsSet_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesImmediatelyIfANewArtifactIsSet() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setSaveFunction(save); QVERIFY(model.hasSaveFunction()); model.setArtifact(artifact); QSignalSpy spy(&model, signal.constData()); // WHEN model.setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); + QCOMPARE(spy.takeFirst().at(0), propertyValue); QCOMPARE(model.property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply immediately) model.setArtifact(Domain::Task::Ptr::create()); // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); savedArtifact.clear(); // WHEN (nothing else happens after a delay) QTest::qWait(model.autoSaveDelay() + 50); // THEN QVERIFY(!savedArtifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldApplyChangesImmediatelyIfDeleted_data() { shouldReactToArtifactPropertyChanges_data(); } void shouldApplyChangesImmediatelyIfDeleted() { // GIVEN QFETCH(Domain::Artifact::Ptr, artifact); QFETCH(QByteArray, propertyName); QFETCH(QVariant, propertyValue); QFETCH(QByteArray, signal); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; return new FakeJob(this); }; auto model = new Presentation::ArtifactEditorModel; model->setSaveFunction(save); QVERIFY(model->hasSaveFunction()); model->setArtifact(artifact); QSignalSpy spy(model, signal.constData()); // WHEN model->setProperty(propertyName, propertyValue); // THEN QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst(), propertyValue); + QCOMPARE(spy.takeFirst().at(0), propertyValue); QCOMPARE(model->property(propertyName), propertyValue); QVERIFY(artifact->property(propertyName) != propertyValue); QVERIFY(!savedArtifact); // WHEN (apply immediately) delete model; // THEN QCOMPARE(savedArtifact, artifact); QCOMPARE(artifact->property(propertyName), propertyValue); } void shouldLaunchDelegation() { // GIVEN auto task = Domain::Task::Ptr::create(); auto expectedDelegate = Domain::Task::Delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com")); auto delegatedTask = Domain::Task::Ptr(); auto delegate = Domain::Task::Delegate(); auto delegateFunction = [this, &delegatedTask, &delegate] (const Domain::Task::Ptr &task, const Domain::Task::Delegate &d) { delegatedTask = task; delegate = d; return new FakeJob(this); }; Presentation::ArtifactEditorModel model; model.setDelegateFunction(delegateFunction); QVERIFY(model.hasDelegateFunction()); model.setArtifact(task); // WHEN model.delegate(QStringLiteral("John Doe"), QStringLiteral("john@doe.com")); // THEN QCOMPARE(delegatedTask, task); QCOMPARE(delegate, expectedDelegate); QVERIFY(!task->delegate().isValid()); } void shouldGetAnErrorMessageWhenSaveFailed() { // GIVEN auto task = Domain::Task::Ptr::create(); task->setTitle(QStringLiteral("Task 1")); auto savedArtifact = Domain::Artifact::Ptr(); auto save = [this, &savedArtifact] (const Domain::Artifact::Ptr &artifact) { savedArtifact = artifact; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); return job; }; auto model = new Presentation::ArtifactEditorModel; model->setSaveFunction(save); QVERIFY(model->hasSaveFunction()); FakeErrorHandler errorHandler; model->setErrorHandler(&errorHandler); model->setArtifact(task); // WHEN model->setProperty("title", "Foo"); delete model; // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task Task 1: Foo")); } }; ZANSHIN_TEST_MAIN(ArtifactEditorModelTest) #include "artifacteditormodeltest.moc" diff --git a/tests/units/testlib/akonadifakedatatest.cpp b/tests/units/testlib/akonadifakedatatest.cpp index bf2eeda9..0755024d 100644 --- a/tests/units/testlib/akonadifakedatatest.cpp +++ b/tests/units/testlib/akonadifakedatatest.cpp @@ -1,622 +1,622 @@ /* This file is part of Zanshin Copyright 2015 Kevin Ottens This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "testlib/akonadifakedata.h" #include "akonadi/akonadimonitorinterface.h" #include namespace QTest { template inline bool zCompareHelper(bool isOk, const T &left, const T &right, const char *actual, const char *expected, const char *file, int line) { return compare_helper(isOk, isOk ? "COMPARE()" : "Compared values are not the same", toString(left), toString(right), actual, expected, file, line); } // More aggressive compare to make sure we just don't get collections with ids out template <> inline bool qCompare(const Akonadi::Collection &left, const Akonadi::Collection &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.displayName() == right.displayName()), left, right, actual, expected, file, line); } // More aggressive compare to make sure we just don't get tags with ids out template <> inline bool qCompare(const Akonadi::Tag &left, const Akonadi::Tag &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.name() == right.name()), left, right, actual, expected, file, line); } // More aggressive compare to make sure we just don't get items with ids out template <> inline bool qCompare(const Akonadi::Item &left, const Akonadi::Item &right, const char *actual, const char *expected, const char *file, int line) { return zCompareHelper((left == right) && (left.payloadData() == right.payloadData()), left, right, actual, expected, file, line); } } class AkonadiFakeDataTest : public QObject { Q_OBJECT public: explicit AkonadiFakeDataTest(QObject *parent = Q_NULLPTR) : QObject(parent) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); } private slots: void shouldBeInitiallyEmpty() { // GIVEN auto data = Testlib::AkonadiFakeData(); // THEN QVERIFY(data.collections().isEmpty()); QVERIFY(data.tags().isEmpty()); QVERIFY(data.items().isEmpty()); } void shouldCreateCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionAdded); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); auto c2 = Akonadi::Collection(43); c2.setName(QStringLiteral("43")); const auto colSet = QSet() << c1 << c2; // WHEN data.createCollection(c1); data.createCollection(c2); // THEN QCOMPARE(data.collections().toList().toSet(), colSet); QCOMPARE(data.collection(c1.id()), c1); QCOMPARE(data.collection(c2.id()), c2); QCOMPARE(spy.size(), 2); - QCOMPARE(spy.takeFirst().takeFirst().value(), c1); - QCOMPARE(spy.takeFirst().takeFirst().value(), c2); + QCOMPARE(spy.takeFirst().at(0).value(), c1); + QCOMPARE(spy.takeFirst().at(0).value(), c2); } void shouldModifyCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionChanged); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(c1.id()); c2.setName(QStringLiteral("42-bis")); // WHEN data.modifyCollection(c2); // THEN QCOMPARE(data.collections().size(), 1); QCOMPARE(data.collection(c1.id()), c2); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), c2); + QCOMPARE(spy.takeFirst().at(0).value(), c2); } void shouldNotLooseParentCollectionOnModifyCollection() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto root = Akonadi::Collection(42); root.setName(QStringLiteral("root")); data.createCollection(root); auto c1 = Akonadi::Collection(43); c1.setName(QStringLiteral("43")); c1.setParentCollection(Akonadi::Collection(root.id())); data.createCollection(c1); auto c2 = Akonadi::Collection(c1.id()); c2.setName(QStringLiteral("43-bis")); // WHEN data.modifyCollection(c2); // THEN QCOMPARE(data.collections().size(), 2); QCOMPARE(data.collection(c1.id()), c2); QCOMPARE(data.collection(c1.id()).parentCollection().id(), root.id()); } void shouldListChildCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); auto c2 = Akonadi::Collection(43); c2.setName(QStringLiteral("43")); c2.setParentCollection(Akonadi::Collection(42)); const auto colSet = QSet() << c2; // WHEN data.createCollection(c1); data.createCollection(c2); // THEN QVERIFY(data.childCollections(c2.id()).isEmpty()); QCOMPARE(data.childCollections(c1.id()).toList().toSet(), colSet); } void shouldReparentCollectionsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); c2.setName(QStringLiteral("43")); data.createCollection(c2); auto c3 = Akonadi::Collection(44); c3.setParentCollection(Akonadi::Collection(42)); data.createCollection(c3); // WHEN c3.setParentCollection(Akonadi::Collection(43)); data.modifyCollection(c3); // THEN QVERIFY(data.childCollections(c1.id()).isEmpty()); QCOMPARE(data.childCollections(c2.id()).size(), 1); - QCOMPARE(data.childCollections(c2.id()).first(), c3); + QCOMPARE(data.childCollections(c2.id()).at(0), c3); } void shouldRemoveCollections() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::collectionRemoved); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); c2.setName(QStringLiteral("43")); c2.setParentCollection(Akonadi::Collection(42)); data.createCollection(c2); auto c3 = Akonadi::Collection(44); c3.setName(QStringLiteral("44")); c3.setParentCollection(Akonadi::Collection(43)); data.createCollection(c3); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(43)); data.createItem(i1); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); i2.setParentCollection(Akonadi::Collection(44)); data.createItem(i2); // WHEN data.removeCollection(c2); // THEN QCOMPARE(data.collections().size(), 1); - QCOMPARE(data.collections().first(), c1); + QCOMPARE(data.collections().at(0), c1); QVERIFY(!data.collection(c2.id()).isValid()); QVERIFY(!data.collection(c3.id()).isValid()); QVERIFY(data.childCollections(c1.id()).isEmpty()); QVERIFY(data.childCollections(c2.id()).isEmpty()); QVERIFY(data.childCollections(c3.id()).isEmpty()); QVERIFY(data.items().isEmpty()); QVERIFY(!data.item(i1.id()).isValid()); QVERIFY(!data.item(i2.id()).isValid()); QVERIFY(data.childItems(c2.id()).isEmpty()); QVERIFY(data.childItems(c3.id()).isEmpty()); QCOMPARE(spy.size(), 2); - QCOMPARE(spy.takeFirst().takeFirst().value(), c3); - QCOMPARE(spy.takeFirst().takeFirst().value(), c2); + QCOMPARE(spy.takeFirst().at(0).value(), c3); + QCOMPARE(spy.takeFirst().at(0).value(), c2); } void shouldCreateTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagAdded); auto t1 = Akonadi::Tag(42); t1.setName(QStringLiteral("42")); auto t2 = Akonadi::Tag(43); t2.setName(QStringLiteral("43")); // WHEN data.createTag(t1); data.createTag(t2); // THEN QCOMPARE(data.tags().size(), 2); QVERIFY(data.tags().contains(t1)); QVERIFY(data.tags().contains(t2)); QCOMPARE(data.tag(t1.id()), t1); QCOMPARE(data.tag(t2.id()), t2); QCOMPARE(spy.size(), 2); - QCOMPARE(spy.takeFirst().takeFirst().value(), t1); - QCOMPARE(spy.takeFirst().takeFirst().value(), t2); + QCOMPARE(spy.takeFirst().at(0).value(), t1); + QCOMPARE(spy.takeFirst().at(0).value(), t2); } void shouldModifyTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::tagChanged); auto t1 = Akonadi::Tag(42); t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(t1.id()); t2.setName(QStringLiteral("42-bis")); // WHEN data.modifyTag(t2); // THEN QCOMPARE(data.tags().size(), 1); QCOMPARE(data.tag(t1.id()), t2); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), t2); + QCOMPARE(spy.takeFirst().at(0).value(), t2); } void shouldRemoveTags() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy tagSpy(monitor.data(), &Akonadi::MonitorInterface::tagRemoved); QSignalSpy itemSpy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); auto c1 = Akonadi::Collection(42); data.createCollection(c1); auto t1 = Akonadi::Tag(42); t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(43); t2.setName(QStringLiteral("43")); data.createTag(t2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(c1); i1.setTag(Akonadi::Tag(t1.id())); data.createItem(i1); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); i2.setParentCollection(c1); i2.setTag(Akonadi::Tag(t2.id())); data.createItem(i2); const auto itemSet = QSet() << i1 << i2; // WHEN data.removeTag(t2); // THEN QCOMPARE(data.tags().size(), 1); - QCOMPARE(data.tags().first(), t1); + QCOMPARE(data.tags().at(0), t1); QVERIFY(!data.tag(t2.id()).isValid()); QCOMPARE(data.tagItems(t1.id()).size(), 1); - QCOMPARE(data.tagItems(t1.id()).first(), i1); + QCOMPARE(data.tagItems(t1.id()).at(0), i1); QVERIFY(data.tagItems(t2.id()).isEmpty()); QCOMPARE(data.items().toList().toSet(), itemSet); QVERIFY(data.item(i1.id()).isValid()); QVERIFY(data.item(i2.id()).isValid()); QVERIFY(!data.item(i2.id()).tags().contains(t2)); QCOMPARE(tagSpy.size(), 1); - QCOMPARE(tagSpy.takeFirst().takeFirst().value(), t2); + QCOMPARE(tagSpy.takeFirst().at(0).value(), t2); QCOMPARE(itemSpy.size(), 1); - QCOMPARE(itemSpy.first().first().value(), i2); - QVERIFY(!itemSpy.first().first().value().tags().contains(t2)); + QCOMPARE(itemSpy.first().at(0).value(), i2); + QVERIFY(!itemSpy.first().at(0).value().tags().contains(t2)); } void shouldCreateItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemAdded); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); auto i2 = Akonadi::Item(43); i2.setPayloadFromData("43"); const auto itemSet = QSet() << i1 << i2; // WHEN data.createItem(i1); data.createItem(i2); // THEN QCOMPARE(data.items().toList().toSet(), itemSet); QCOMPARE(data.item(i1.id()), i1); QCOMPARE(data.item(i2.id()), i2); QCOMPARE(spy.size(), 2); - QCOMPARE(spy.takeFirst().takeFirst().value(), i1); - QCOMPARE(spy.takeFirst().takeFirst().value(), i2); + QCOMPARE(spy.takeFirst().at(0).value(), i1); + QCOMPARE(spy.takeFirst().at(0).value(), i2); } void shouldModifyItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); QSignalSpy moveSpy(monitor.data(), &Akonadi::MonitorInterface::itemMoved); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); auto i2 = Akonadi::Item(i1.id()); i2.setPayloadFromData("42-bis"); i2.setParentCollection(Akonadi::Collection(42)); // WHEN data.modifyItem(i2); // THEN QCOMPARE(data.items().size(), 1); QCOMPARE(data.item(i1.id()), i2); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), i2); + QCOMPARE(spy.takeFirst().at(0).value(), i2); QCOMPARE(moveSpy.size(), 0); } void shouldNotLooseParentCollectionOnModifyItem() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); auto i2 = Akonadi::Item(i1.id()); i2.setPayloadFromData("42-bis"); // WHEN data.modifyItem(i2); // THEN QCOMPARE(data.items().size(), 1); QCOMPARE(data.item(i1.id()), i2); QCOMPARE(data.item(i1.id()).parentCollection().id(), c1.id()); } void shouldListChildItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); // WHEN data.createItem(i1); // THEN QCOMPARE(data.childItems(c1.id()).size(), 1); - QCOMPARE(data.childItems(c1.id()).first(), i1); + QCOMPARE(data.childItems(c1.id()).at(0), i1); } void shouldReparentItemsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemMoved); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto c2 = Akonadi::Collection(43); c2.setName(QStringLiteral("43")); data.createCollection(c2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); // WHEN i1.setPayloadFromData("42-bis"); i1.setParentCollection(Akonadi::Collection(43)); data.modifyItem(i1); // THEN QVERIFY(data.childItems(c1.id()).isEmpty()); QCOMPARE(data.childItems(c2.id()).size(), 1); - QCOMPARE(data.childItems(c2.id()).first(), i1); + QCOMPARE(data.childItems(c2.id()).at(0), i1); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), i1); + QCOMPARE(spy.takeFirst().at(0).value(), i1); } void shouldListTagItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); auto t1 = Akonadi::Tag(42); t1.setName(QStringLiteral("42")); data.createTag(t1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setTag(Akonadi::Tag(42)); // WHEN data.createItem(i1); // THEN QCOMPARE(data.tagItems(t1.id()).size(), 1); - QCOMPARE(data.tagItems(t1.id()).first(), i1); + QCOMPARE(data.tagItems(t1.id()).at(0), i1); } void shouldRetagItemsOnModify() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemChanged); auto t1 = Akonadi::Tag(42); t1.setName(QStringLiteral("42")); data.createTag(t1); auto t2 = Akonadi::Tag(43); t2.setName(QStringLiteral("43")); data.createTag(t2); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setTag(Akonadi::Tag(42)); data.createItem(i1); // WHEN i1.setPayloadFromData("42-bis"); i1.clearTag(Akonadi::Tag(42)); i1.setTag(Akonadi::Tag(43)); data.modifyItem(i1); // THEN QVERIFY(data.tagItems(t1.id()).isEmpty()); QCOMPARE(data.tagItems(t2.id()).size(), 1); - QCOMPARE(data.tagItems(t2.id()).first(), i1); + QCOMPARE(data.tagItems(t2.id()).at(0), i1); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), i1); + QCOMPARE(spy.takeFirst().at(0).value(), i1); } void shouldRemoveItems() { // GIVEN auto data = Testlib::AkonadiFakeData(); QScopedPointer monitor(data.createMonitor()); QSignalSpy spy(monitor.data(), &Akonadi::MonitorInterface::itemRemoved); auto c1 = Akonadi::Collection(42); c1.setName(QStringLiteral("42")); data.createCollection(c1); auto i1 = Akonadi::Item(42); i1.setPayloadFromData("42"); i1.setParentCollection(Akonadi::Collection(42)); data.createItem(i1); // WHEN data.removeItem(i1); // THEN QVERIFY(data.items().isEmpty()); QVERIFY(!data.item(i1.id()).isValid()); QVERIFY(data.childItems(c1.id()).isEmpty()); QCOMPARE(spy.size(), 1); - QCOMPARE(spy.takeFirst().takeFirst().value(), i1); + QCOMPARE(spy.takeFirst().at(0).value(), i1); } }; ZANSHIN_TEST_MAIN(AkonadiFakeDataTest) #include "akonadifakedatatest.moc"