diff --git a/src/presentation/CMakeLists.txt b/src/presentation/CMakeLists.txt index 54ce205e..65d8e3d6 100644 --- a/src/presentation/CMakeLists.txt +++ b/src/presentation/CMakeLists.txt @@ -1,24 +1,24 @@ set(presentation_SRCS applicationmodel.cpp editormodel.cpp availablepagesmodel.cpp availablepagessortfilterproxymodel.cpp availablesourcesmodel.cpp contextpagemodel.cpp errorhandler.cpp errorhandlingmodelbase.cpp + inboxpagemodel.cpp metatypes.cpp pagemodel.cpp projectpagemodel.cpp querytreemodelbase.cpp runningtaskmodelinterface.cpp runningtaskmodel.cpp taskfilterproxymodel.cpp - taskinboxpagemodel.cpp tasklistmodel.cpp taskapplicationmodel.cpp workdaypagemodel.cpp ) add_library(presentation STATIC ${presentation_SRCS}) target_link_libraries(presentation Qt5::Core Qt5::Gui KF5::I18n domain utils) diff --git a/src/presentation/availablepagesmodel.cpp b/src/presentation/availablepagesmodel.cpp index 3c9c52c9..8529b6a4 100644 --- a/src/presentation/availablepagesmodel.cpp +++ b/src/presentation/availablepagesmodel.cpp @@ -1,317 +1,317 @@ /* 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 "availablepagesmodel.h" #include #include #include #include "domain/contextqueries.h" #include "domain/contextrepository.h" #include "domain/projectqueries.h" #include "domain/projectrepository.h" #include "domain/taskrepository.h" #include "presentation/availablepagessortfilterproxymodel.h" #include "presentation/contextpagemodel.h" +#include "presentation/inboxpagemodel.h" #include "presentation/metatypes.h" #include "presentation/projectpagemodel.h" #include "presentation/querytreemodel.h" -#include "presentation/taskinboxpagemodel.h" #include "presentation/workdaypagemodel.h" #include "utils/jobhandler.h" #include "utils/datetime.h" using namespace Presentation; AvailablePagesModel::AvailablePagesModel(const Domain::DataSourceQueries::Ptr &dataSourceQueries, - const Domain::ProjectQueries::Ptr &projectQueries, - const Domain::ProjectRepository::Ptr &projectRepository, - const Domain::ContextQueries::Ptr &contextQueries, - const Domain::ContextRepository::Ptr &contextRepository, - const Domain::TaskQueries::Ptr &taskQueries, - const Domain::TaskRepository::Ptr &taskRepository, - QObject *parent) + const Domain::ProjectQueries::Ptr &projectQueries, + const Domain::ProjectRepository::Ptr &projectRepository, + const Domain::ContextQueries::Ptr &contextQueries, + const Domain::ContextRepository::Ptr &contextRepository, + const Domain::TaskQueries::Ptr &taskQueries, + const Domain::TaskRepository::Ptr &taskRepository, + QObject *parent) : QObject(parent), m_pageListModel(Q_NULLPTR), m_sortProxyModel(Q_NULLPTR), m_dataSourceQueries(dataSourceQueries), m_projectQueries(projectQueries), m_projectRepository(projectRepository), m_contextQueries(contextQueries), m_contextRepository(contextRepository), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } QAbstractItemModel *AvailablePagesModel::pageListModel() { if (!m_pageListModel) m_pageListModel = createPageListModel(); if (!m_sortProxyModel) { m_sortProxyModel = new AvailablePagesSortFilterProxyModel(this); m_sortProxyModel->setSourceModel(m_pageListModel); } return m_sortProxyModel; } QObject *AvailablePagesModel::createPageForIndex(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (object == m_inboxObject) { - auto inboxPageModel = new TaskInboxPageModel(m_taskQueries, - m_taskRepository, - this); + auto inboxPageModel = new InboxPageModel(m_taskQueries, + m_taskRepository, + this); inboxPageModel->setErrorHandler(errorHandler()); return inboxPageModel; } else if (object == m_workdayObject) { auto workdayPageModel = new WorkdayPageModel(m_taskQueries, m_taskRepository, this); workdayPageModel->setErrorHandler(errorHandler()); return workdayPageModel; } else if (auto project = object.objectCast()) { auto projectPageModel = new ProjectPageModel(project, m_projectQueries, m_projectRepository, m_taskQueries, m_taskRepository, this); projectPageModel->setErrorHandler(errorHandler()); return projectPageModel; } else if (auto context = object.objectCast()) { auto contextPageModel = new ContextPageModel(context, m_contextQueries, m_contextRepository, m_taskQueries, m_taskRepository, this); contextPageModel->setErrorHandler(errorHandler()); return contextPageModel; } return Q_NULLPTR; } void AvailablePagesModel::addProject(const QString &name, const Domain::DataSource::Ptr &source) { auto project = Domain::Project::Ptr::create(); project->setName(name); const auto job = m_projectRepository->create(project, source); installHandler(job, i18n("Cannot add project %1 in dataSource %2", name, source->name())); } void AvailablePagesModel::addContext(const QString &name) { auto context = Domain::Context::Ptr::create(); context->setName(name); const auto job = m_contextRepository->create(context); installHandler(job, i18n("Cannot add context %1", name)); } void AvailablePagesModel::removeItem(const QModelIndex &index) { QObjectPtr object = index.data(QueryTreeModelBase::ObjectRole).value(); if (auto project = object.objectCast()) { const auto job = m_projectRepository->remove(project); installHandler(job, i18n("Cannot remove project %1", project->name())); } else if (auto context = object.objectCast()) { const auto job = m_contextRepository->remove(context); installHandler(job, i18n("Cannot remove context %1", context->name())); } else { Q_ASSERT(false); } } QAbstractItemModel *AvailablePagesModel::createPageListModel() { m_inboxObject = QObjectPtr::create(); m_inboxObject->setProperty("name", i18n("Inbox")); m_workdayObject = QObjectPtr::create(); m_workdayObject->setProperty("name", i18n("Workday")); m_projectsObject = QObjectPtr::create(); m_projectsObject->setProperty("name", i18n("Projects")); m_contextsObject = QObjectPtr::create(); m_contextsObject->setProperty("name", i18n("Contexts")); m_rootsProvider = Domain::QueryResultProvider::Ptr::create(); m_rootsProvider->append(m_inboxObject); m_rootsProvider->append(m_workdayObject); m_rootsProvider->append(m_projectsObject); m_rootsProvider->append(m_contextsObject); auto query = [this](const QObjectPtr &object) -> Domain::QueryResultInterface::Ptr { if (!object) return Domain::QueryResult::create(m_rootsProvider); else if (object == m_projectsObject) return Domain::QueryResult::copy(m_dataSourceQueries->findAllSelected()); else if (object == m_contextsObject) return Domain::QueryResult::copy(m_contextQueries->findAll()); else if (const auto source = object.objectCast()) return Domain::QueryResult::copy(m_dataSourceQueries->findProjects(source)); else return Domain::QueryResult::Ptr(); }; auto flags = [this](const QObjectPtr &object) { const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled; const Qt::ItemFlags immutableNodeFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled; const Qt::ItemFlags structureNodeFlags = Qt::NoItemFlags; return object.objectCast() ? defaultFlags : object.objectCast() ? defaultFlags : object == m_inboxObject ? immutableNodeFlags : object == m_workdayObject ? immutableNodeFlags : structureNodeFlags; }; auto data = [this](const QObjectPtr &object, int role, int) -> QVariant { if (role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::DecorationRole && role != QueryTreeModelBase::IconNameRole) { return QVariant(); } if (role == Qt::EditRole && (object == m_inboxObject || object == m_workdayObject || object == m_projectsObject || object == m_contextsObject || object.objectCast())) { return QVariant(); } if (role == Qt::DisplayRole || role == Qt::EditRole) { return object->property("name").toString(); } else if (role == Qt::DecorationRole || role == QueryTreeModelBase::IconNameRole) { const QString iconName = object == m_inboxObject ? QStringLiteral("mail-folder-inbox") : (object == m_workdayObject) ? QStringLiteral("go-jump-today") : (object == m_projectsObject) ? QStringLiteral("folder") : (object == m_contextsObject) ? QStringLiteral("folder") : object.objectCast() ? QStringLiteral("folder") : object.objectCast() ? QStringLiteral("view-pim-notes") : QStringLiteral("view-pim-tasks"); if (role == Qt::DecorationRole) return QVariant::fromValue(QIcon::fromTheme(iconName)); else return iconName; } else { return QVariant(); } }; auto setData = [this](const QObjectPtr &object, const QVariant &value, int role) { if (role != Qt::EditRole) { return false; } if (object == m_inboxObject || object == m_workdayObject || object == m_projectsObject || object == m_contextsObject || object.objectCast()) { return false; } if (auto project = object.objectCast()) { const auto currentName = project->name(); project->setName(value.toString()); const auto job = m_projectRepository->update(project); installHandler(job, i18n("Cannot modify project %1", currentName)); } else if (auto context = object.objectCast()) { const auto currentName = context->name(); context->setName(value.toString()); const auto job = m_contextRepository->update(context); installHandler(job, i18n("Cannot modify context %1", currentName)); } else { Q_ASSERT(false); } return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const QObjectPtr &object) { if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedTasks = mimeData->property("objects").value(); if (droppedTasks.isEmpty()) return false; if (auto project = object.objectCast()) { foreach (const auto &task, droppedTasks) { const auto job = m_projectRepository->associate(project, task); installHandler(job, i18n("Cannot add %1 to project %2", task->title(), project->name())); } return true; } else if (auto context = object.objectCast()) { foreach (const auto &task, droppedTasks) { const auto job = m_contextRepository->associate(context, task); installHandler(job, i18n("Cannot add %1 to context %2", task->title(), context->name())); } return true; } else if (object == m_inboxObject) { foreach (const auto &task, droppedTasks) { const auto job = m_projectRepository->dissociate(task); installHandler(job, i18n("Cannot move %1 to Inbox", task->title())); Utils::JobHandler::install(job, [this, task] { const auto dissociateJob = m_taskRepository->dissociateAll(task); installHandler(dissociateJob, i18n("Cannot move task %1 to Inbox", task->title())); }); } return true; } else if (object == m_workdayObject) { foreach (const auto &task, droppedTasks) { task->setStartDate(Utils::DateTime::currentDate()); const auto job = m_taskRepository->update(task); installHandler(job, i18n("Cannot update task %1 to Workday", task->title())); } return true; } return false; }; auto drag = [](const QObjectPtrList &) -> QMimeData* { return Q_NULLPTR; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, nullptr, this); } diff --git a/src/presentation/taskinboxpagemodel.cpp b/src/presentation/inboxpagemodel.cpp similarity index 92% rename from src/presentation/taskinboxpagemodel.cpp rename to src/presentation/inboxpagemodel.cpp index ef144587..6da645f0 100644 --- a/src/presentation/taskinboxpagemodel.cpp +++ b/src/presentation/inboxpagemodel.cpp @@ -1,179 +1,179 @@ /* 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 "taskinboxpagemodel.h" +#include "inboxpagemodel.h" #include #include #include "presentation/querytreemodel.h" using namespace Presentation; -TaskInboxPageModel::TaskInboxPageModel(const Domain::TaskQueries::Ptr &taskQueries, - const Domain::TaskRepository::Ptr &taskRepository, - QObject *parent) +InboxPageModel::InboxPageModel(const Domain::TaskQueries::Ptr &taskQueries, + const Domain::TaskRepository::Ptr &taskRepository, + QObject *parent) : PageModel(parent), m_taskQueries(taskQueries), m_taskRepository(taskRepository) { } -Domain::Task::Ptr TaskInboxPageModel::addItem(const QString &title, const QModelIndex &parentIndex) +Domain::Task::Ptr InboxPageModel::addItem(const QString &title, const QModelIndex &parentIndex) { const auto parentData = parentIndex.data(QueryTreeModelBase::ObjectRole); const auto parentTask = parentData.value(); auto task = Domain::Task::Ptr::create(); task->setTitle(title); const auto job = parentTask ? m_taskRepository->createChild(task, parentTask) : m_taskRepository->create(task); installHandler(job, i18n("Cannot add task %1 in Inbox", title)); return task; } -void TaskInboxPageModel::removeItem(const QModelIndex &index) +void InboxPageModel::removeItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModelBase::ObjectRole); auto task = data.value(); Q_ASSERT(task); const auto job = m_taskRepository->remove(task); installHandler(job, i18n("Cannot remove task %1 from Inbox", task->title())); } -void TaskInboxPageModel::promoteItem(const QModelIndex &index) +void InboxPageModel::promoteItem(const QModelIndex &index) { QVariant data = index.data(QueryTreeModelBase::ObjectRole); auto task = data.value(); Q_ASSERT(task); const auto job = m_taskRepository->promoteToProject(task); installHandler(job, i18n("Cannot promote task %1 to be a project", task->title())); } -QAbstractItemModel *TaskInboxPageModel::createCentralListModel() +QAbstractItemModel *InboxPageModel::createCentralListModel() { using AdditionalInfo = Domain::QueryResult::Ptr; auto query = [this](const Domain::Task::Ptr &task) -> Domain::QueryResultInterface::Ptr { if (!task) return m_taskQueries->findInboxTopLevel(); else return m_taskQueries->findChildren(task); }; auto flags = [](const Domain::Task::Ptr &) { return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled; }; auto data = [](const Domain::Task::Ptr &task, int role, const AdditionalInfo &dataSourceQueryResult) -> QVariant { switch (role) { case Qt::DisplayRole: case Qt::EditRole: return task->title(); case Qt::CheckStateRole: return task->isDone() ? Qt::Checked : Qt::Unchecked; case Presentation::QueryTreeModelBase::AdditionalInfoRole: if (dataSourceQueryResult && !dataSourceQueryResult->data().isEmpty()) { Domain::DataSource::Ptr dataSource = dataSourceQueryResult->data().at(0); return dataSource->name(); } return QString(); default: break; } return QVariant(); }; auto fetchAdditionalInfo = [this](const QModelIndex &index, const Domain::Task::Ptr &task) -> AdditionalInfo { if (index.parent().isValid()) // children are in the same collection as their parent, so the same datasource return nullptr; AdditionalInfo datasourceQueryResult = m_taskQueries->findDataSource(task); if (datasourceQueryResult) { QPersistentModelIndex persistentIndex(index); datasourceQueryResult->addPostInsertHandler([persistentIndex](const Domain::DataSource::Ptr &, int) { // When a datasource was found (inserted into the result), update the rendering of the item auto model = const_cast(persistentIndex.model()); model->dataChanged(persistentIndex, persistentIndex); }); } return datasourceQueryResult; }; auto setData = [this](const Domain::Task::Ptr &task, const QVariant &value, int role) { if (role != Qt::EditRole && role != Qt::CheckStateRole) { return false; } const auto currentTitle = task->title(); if (role == Qt::EditRole) task->setTitle(value.toString()); else task->setDone(value.toInt() == Qt::Checked); const auto job = m_taskRepository->update(task); installHandler(job, i18n("Cannot modify task %1 in Inbox", currentTitle)); return true; }; auto drop = [this](const QMimeData *mimeData, Qt::DropAction, const Domain::Task::Ptr &parentTask) { if (!mimeData->hasFormat(QStringLiteral("application/x-zanshin-object"))) return false; auto droppedTasks = mimeData->property("objects").value(); if (droppedTasks.isEmpty()) return false; foreach(const auto &childTask, droppedTasks) { if (parentTask) { const auto job = m_taskRepository->associate(parentTask, childTask); installHandler(job, i18n("Cannot move task %1 as sub-task of %2", childTask->title(), parentTask->title())); } else { const auto job = m_taskRepository->dissociate(childTask); installHandler(job, i18n("Cannot deparent task %1 from its parent", childTask->title())); } } return true; }; auto drag = [](const Domain::Task::List &tasks) -> QMimeData* { if (tasks.isEmpty()) return Q_NULLPTR; auto data = new QMimeData; data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(tasks)); return data; }; return new QueryTreeModel(query, flags, data, setData, drop, drag, fetchAdditionalInfo, this); } diff --git a/src/presentation/taskinboxpagemodel.h b/src/presentation/inboxpagemodel.h similarity index 80% rename from src/presentation/taskinboxpagemodel.h rename to src/presentation/inboxpagemodel.h index ad8e0cbe..60b38126 100644 --- a/src/presentation/taskinboxpagemodel.h +++ b/src/presentation/inboxpagemodel.h @@ -1,56 +1,56 @@ /* 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. */ -#ifndef PRESENTATION_TASKINBOXPAGEMODEL_H -#define PRESENTATION_TASKINBOXPAGEMODEL_H +#ifndef PRESENTATION_INBOXPAGEMODEL_H +#define PRESENTATION_INBOXPAGEMODEL_H #include "presentation/pagemodel.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" namespace Presentation { -class TaskInboxPageModel : public PageModel +class InboxPageModel : public PageModel { Q_OBJECT public: - explicit TaskInboxPageModel(const Domain::TaskQueries::Ptr &taskQueries, - const Domain::TaskRepository::Ptr &taskRepository, - QObject *parent = Q_NULLPTR); + explicit InboxPageModel(const Domain::TaskQueries::Ptr &taskQueries, + const Domain::TaskRepository::Ptr &taskRepository, + QObject *parent = Q_NULLPTR); Domain::Task::Ptr addItem(const QString &title, const QModelIndex &parentIndex = QModelIndex()) Q_DECL_OVERRIDE; void removeItem(const QModelIndex &index) Q_DECL_OVERRIDE; void promoteItem(const QModelIndex &index) Q_DECL_OVERRIDE; private: QAbstractItemModel *createCentralListModel() Q_DECL_OVERRIDE; Domain::TaskQueries::Ptr m_taskQueries; Domain::TaskRepository::Ptr m_taskRepository; }; } -#endif // PRESENTATION_TASKINBOXPAGEMODEL_H +#endif // PRESENTATION_INBOXPAGEMODEL_H diff --git a/tests/units/presentation/CMakeLists.txt b/tests/units/presentation/CMakeLists.txt index d3a12b53..b5f3b6c1 100644 --- a/tests/units/presentation/CMakeLists.txt +++ b/tests/units/presentation/CMakeLists.txt @@ -1,20 +1,20 @@ zanshin_auto_tests( applicationmodeltest editormodeltest availablepagesmodeltest availablepagessortfilterproxymodeltest availablesourcesmodeltest errorhandlertest errorhandlingmodelbasetest + inboxpagemodeltest metatypestest pagemodeltest projectpagemodeltest querytreemodeltest runningtaskmodeltest taskapplicationmodeltest taskfilterproxymodeltest - taskinboxpagemodeltest tasklistmodeltest contextpagemodeltest workdaypagemodeltest ) diff --git a/tests/units/presentation/availablepagesmodeltest.cpp b/tests/units/presentation/availablepagesmodeltest.cpp index 47ed213b..24b5a73e 100644 --- a/tests/units/presentation/availablepagesmodeltest.cpp +++ b/tests/units/presentation/availablepagesmodeltest.cpp @@ -1,1247 +1,1247 @@ /* 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 #include #include #include "utils/mockobject.h" #include "utils/datetime.h" #include "presentation/availablepagesmodel.h" #include "presentation/contextpagemodel.h" #include "presentation/errorhandler.h" +#include "presentation/inboxpagemodel.h" #include "presentation/projectpagemodel.h" #include "presentation/querytreemodelbase.h" -#include "presentation/taskinboxpagemodel.h" #include "presentation/workdaypagemodel.h" #include "testlib/fakejob.h" using namespace mockitopp; using namespace mockitopp::matcher; class FakeErrorHandler : public Presentation::ErrorHandler { public: void doDisplayMessage(const QString &message) override { m_message = message; } QString m_message; }; class AvailablePagesModelTest : public QObject { Q_OBJECT private slots: void shouldListAvailablePages() { // GIVEN // Two selected data sources auto source1 = Domain::DataSource::Ptr::create(); source1->setName("source1"); auto source2 = Domain::DataSource::Ptr::create(); source2->setName("source2"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source1); sourceProvider->append(source2); // Two projects under source 1 auto project11 = Domain::Project::Ptr::create(); project11->setName(QStringLiteral("Project 11")); auto project12 = Domain::Project::Ptr::create(); project12->setName(QStringLiteral("Project 12")); auto project1Provider = Domain::QueryResultProvider::Ptr::create(); auto project1Result = Domain::QueryResult::create(project1Provider); project1Provider->append(project12); project1Provider->append(project11); // note: reversed order, to test sorting // Two projects under source 2 auto project21 = Domain::Project::Ptr::create(); project21->setName(QStringLiteral("Project 21")); auto project22 = Domain::Project::Ptr::create(); project22->setName(QStringLiteral("Project 22")); auto project2Provider = Domain::QueryResultProvider::Ptr::create(); auto project2Result = Domain::QueryResult::create(project2Provider); project2Provider->append(project22); project2Provider->append(project21); // note: reversed order, to test sorting // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // One task (used for dropping later on) Domain::Task::Ptr taskToDrop(new Domain::Task); Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source1).thenReturn(project1Result); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source2).thenReturn(project2Result); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); const QModelIndex workdayIndex = model->index(1, 0); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex source1Index = model->index(0, 0, projectsIndex); const QModelIndex project11Index = model->index(0, 0, source1Index); const QModelIndex project12Index = model->index(1, 0, source1Index); const QModelIndex source2Index = model->index(1, 0, projectsIndex); const QModelIndex project21Index = model->index(0, 0, source2Index); const QModelIndex project22Index = model->index(1, 0, source2Index); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); const QModelIndex context2Index = model->index(1, 0, contextsIndex); QCOMPARE(model->rowCount(), 4); QCOMPARE(model->rowCount(inboxIndex), 0); QCOMPARE(model->rowCount(workdayIndex), 0); QCOMPARE(model->rowCount(projectsIndex), 2); QCOMPARE(model->rowCount(source1Index), 2); QCOMPARE(model->rowCount(project11Index), 0); QCOMPARE(model->rowCount(project12Index), 0); QCOMPARE(model->rowCount(source2Index), 2); QCOMPARE(model->rowCount(project21Index), 0); QCOMPARE(model->rowCount(project22Index), 0); QCOMPARE(model->rowCount(contextsIndex), 2); QCOMPARE(model->rowCount(context1Index), 0); QCOMPARE(model->rowCount(context2Index), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; QCOMPARE(model->flags(inboxIndex), (defaultFlags & ~(Qt::ItemIsEditable)) | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(workdayIndex), (defaultFlags & ~(Qt::ItemIsEditable)) | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(projectsIndex), Qt::NoItemFlags); QCOMPARE(model->flags(source1Index), Qt::NoItemFlags); QCOMPARE(model->flags(project11Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(project12Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(source2Index), Qt::NoItemFlags); QCOMPARE(model->flags(project21Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(project22Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(contextsIndex), Qt::NoItemFlags); QCOMPARE(model->flags(context1Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(context2Index), defaultFlags | Qt::ItemIsDropEnabled); QCOMPARE(model->data(inboxIndex).toString(), i18n("Inbox")); QCOMPARE(model->data(workdayIndex).toString(), i18n("Workday")); QCOMPARE(model->data(projectsIndex).toString(), i18n("Projects")); QCOMPARE(model->data(source1Index).toString(), source1->name()); QCOMPARE(model->data(project11Index).toString(), project11->name()); QCOMPARE(model->data(project12Index).toString(), project12->name()); QCOMPARE(model->data(source2Index).toString(), source2->name()); QCOMPARE(model->data(project21Index).toString(), project21->name()); QCOMPARE(model->data(project22Index).toString(), project22->name()); QCOMPARE(model->data(contextsIndex).toString(), i18n("Contexts")); QCOMPARE(model->data(context1Index).toString(), context1->name()); QCOMPARE(model->data(context2Index).toString(), context2->name()); QVERIFY(!model->data(inboxIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(workdayIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(projectsIndex, Qt::EditRole).isValid()); QVERIFY(!model->data(source1Index, Qt::EditRole).isValid()); QCOMPARE(model->data(project11Index, Qt::EditRole).toString(), project11->name()); QCOMPARE(model->data(project12Index, Qt::EditRole).toString(), project12->name()); QVERIFY(!model->data(source2Index, Qt::EditRole).isValid()); QCOMPARE(model->data(project21Index, Qt::EditRole).toString(), project21->name()); QCOMPARE(model->data(project22Index, Qt::EditRole).toString(), project22->name()); QVERIFY(!model->data(contextsIndex, Qt::EditRole).isValid()); QCOMPARE(model->data(context1Index, Qt::EditRole).toString(), context1->name()); QCOMPARE(model->data(context2Index, Qt::EditRole).toString(), context2->name()); QCOMPARE(model->data(inboxIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("mail-folder-inbox")); QCOMPARE(model->data(workdayIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("go-jump-today")); QCOMPARE(model->data(projectsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QCOMPARE(model->data(source1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QCOMPARE(model->data(project11Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); QCOMPARE(model->data(project12Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); QCOMPARE(model->data(source2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QCOMPARE(model->data(project21Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); QCOMPARE(model->data(project22Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-tasks")); QCOMPARE(model->data(contextsIndex, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("folder")); QCOMPARE(model->data(context1Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-notes")); QCOMPARE(model->data(context2Index, Presentation::QueryTreeModelBase::IconNameRole).toString(), QStringLiteral("view-pim-notes")); QVERIFY(!model->data(inboxIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(workdayIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(projectsIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(source1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project11Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project12Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(source2Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project21Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(project22Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(contextsIndex, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(context1Index, Qt::CheckStateRole).isValid()); QVERIFY(!model->data(context2Index, Qt::CheckStateRole).isValid()); // WHEN projectRepositoryMock(&Domain::ProjectRepository::update).when(project11).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::update).when(project12).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::update).when(project21).thenReturn(new FakeJob(this)); projectRepositoryMock(&Domain::ProjectRepository::update).when(project22).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::update).when(context1).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::update).when(context2).thenReturn(new FakeJob(this)); QVERIFY(!model->setData(inboxIndex, "Foo")); QVERIFY(!model->setData(projectsIndex, "Foo")); QVERIFY(!model->setData(source1Index, "Foo")); QVERIFY(model->setData(project11Index, "New Project 11")); QVERIFY(model->setData(project12Index, "New Project 12")); QVERIFY(!model->setData(source2Index, "Foo")); QVERIFY(model->setData(project21Index, "New Project 21")); QVERIFY(model->setData(project22Index, "New Project 22")); QVERIFY(!model->setData(contextsIndex, "Foo")); QVERIFY(model->setData(context1Index, "New Context 1")); QVERIFY(model->setData(context2Index, "New Context 2")); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project11).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project12).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project21).exactly(1)); QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::update).when(project22).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::update).when(context1).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::update).when(context2).exactly(1)); QCOMPARE(project11->name(), QStringLiteral("New Project 11")); QCOMPARE(project12->name(), QStringLiteral("New Project 12")); QCOMPARE(project21->name(), QStringLiteral("New Project 21")); QCOMPARE(project22->name(), QStringLiteral("New Project 22")); QCOMPARE(context1->name(), QStringLiteral("New Context 1")); QCOMPARE(context2->name(), QStringLiteral("New Context 2")); // WHEN projectRepositoryMock(&Domain::ProjectRepository::associate).when(project11, taskToDrop).thenReturn(new FakeJob(this)); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, project11Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project11, taskToDrop).exactly(1)); // WHEN a task is dropped on a context contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop).exactly(1)); // WHEN projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, inboxIndex); QTest::qWait(150); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop).exactly(1)); // WHEN Domain::Task::Ptr taskToDrop2(new Domain::Task); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project11, taskToDrop2).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop2)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, project11Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::associate).when(project11, taskToDrop2).exactly(1)); // WHEN two tasks are dropped on a context Domain::Task::Ptr taskToDrop3(new Domain::Task); Domain::Task::Ptr taskToDrop4(new Domain::Task); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop3).thenReturn(new FakeJob(this)); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop4).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop3 << taskToDrop4)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop3).exactly(1)); QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop4).exactly(1)); // WHEN a task is drop on the workday Domain::Task::Ptr taskToDrop5(new Domain::Task); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop5).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop5)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, workdayIndex); // THEN QCOMPARE(taskToDrop5->startDate(), Utils::DateTime::currentDate()); // WHEN two task are drop on the workday Domain::Task::Ptr taskToDrop6(new Domain::Task); Domain::Task::Ptr taskToDrop7(new Domain::Task); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop6).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(taskToDrop7).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop6 << taskToDrop7)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, workdayIndex); // THEN QCOMPARE(taskToDrop6->startDate(), Utils::DateTime::currentDate()); QCOMPARE(taskToDrop7->startDate(), Utils::DateTime::currentDate()); } void shouldCreateInboxPage() { // GIVEN // Empty sources provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // Empty context provider auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // context mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); Utils::MockObject projectRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex inboxIndex = model->index(0, 0); QObject *inboxPage = pages.createPageForIndex(inboxIndex); - QVERIFY(qobject_cast(inboxPage)); + QVERIFY(qobject_cast(inboxPage)); } void shouldCreateWorkdayPage() { // GIVEN // Empty sources provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // Empty context provider auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // context mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); Utils::MockObject projectRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex workdayIndex = model->index(1, 0); QObject *workdayPage = pages.createPageForIndex(workdayIndex); QVERIFY(qobject_cast(workdayPage)); } void shouldCreateProjectsPage() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 11")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 12")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // data source mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); // projects mocking Utils::MockObject projectRepositoryMock; // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex sourceIndex = model->index(0, 0, projectsIndex); const QModelIndex project1Index = model->index(0, 0, sourceIndex); const QModelIndex project2Index = model->index(1, 0, sourceIndex); QObject *projectsPage = pages.createPageForIndex(projectsIndex); QObject *sourcesPage = pages.createPageForIndex(sourceIndex); QObject *project1Page = pages.createPageForIndex(project1Index); QObject *project2Page = pages.createPageForIndex(project2Index); QVERIFY(!projectsPage); QVERIFY(!sourcesPage); QVERIFY(qobject_cast(project1Page)); QCOMPARE(qobject_cast(project1Page)->project(), project1); QVERIFY(qobject_cast(project2Page)); QCOMPARE(qobject_cast(project2Page)->project(), project2); } void shouldCreateContextsPage() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // Empty sources provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); // projects mocking Utils::MockObject projectRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN QAbstractItemModel *model = pages.pageListModel(); // THEN const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); const QModelIndex context2Index = model->index(1, 0, contextsIndex); QObject *contextsPage = pages.createPageForIndex(contextsIndex); QObject *context1Page = pages.createPageForIndex(context1Index); QObject *context2Page = pages.createPageForIndex(context2Index); QVERIFY(!contextsPage); QVERIFY(qobject_cast(context1Page)); QCOMPARE(qobject_cast(context1Page)->context(), context1); QVERIFY(qobject_cast(context2Page)); QCOMPARE(qobject_cast(context2Page)->context(), context2); } void shouldAddProjects() { // GIVEN auto source = Domain::DataSource::Ptr::create(); Utils::MockObject projectRepositoryMock; projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .thenReturn(new FakeJob(this)); Presentation::AvailablePagesModel pages(Domain::DataSourceQueries::Ptr(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN pages.addProject(QStringLiteral("Foo"), source); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .exactly(1)); } void shouldGetAnErrorMessageWhenAddProjectFailed() { // GIVEN auto source = Domain::DataSource::Ptr::create(); source->setName(QStringLiteral("Source1")); Utils::MockObject projectRepositoryMock; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::create).when(any(), any()) .thenReturn(job); Presentation::AvailablePagesModel pages(Domain::DataSourceQueries::Ptr(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), Domain::ContextQueries::Ptr(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); // WHEN pages.addProject(QStringLiteral("Foo"), source); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add project Foo in dataSource Source1: Foo")); } void shouldAddContexts() { // GIVEN Utils::MockObject contextRepositoryMock; contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .thenReturn(new FakeJob(this)); Presentation::AvailablePagesModel pages(Domain::DataSourceQueries::Ptr(), Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); // WHEN pages.addContext(QStringLiteral("Foo")); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .exactly(1)); } void shouldGetAnErrorMessageWhenAddContextFailed() { // GIVEN Utils::MockObject contextRepositoryMock; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::create).when(any()) .thenReturn(job); Presentation::AvailablePagesModel pages(Domain::DataSourceQueries::Ptr(), Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), Domain::ContextQueries::Ptr(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); // WHEN pages.addContext(QStringLiteral("Foo")); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add context Foo: Foo")); } void shouldRemoveProject() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // data source mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); // projects mocking Utils::MockObject projectRepositoryMock; // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex sourceIndex = model->index(0, 0, projectsIndex); const QModelIndex project1Index = model->index(0, 0, sourceIndex); projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).thenReturn(new FakeJob(this)); // WHEN pages.removeItem(project1Index); // THEN QVERIFY(projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveProjectFailed() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // No contexts auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // data source mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); // projects mocking Utils::MockObject projectRepositoryMock; // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), Domain::ContextRepository::Ptr(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex sourceIndex = model->index(0, 0, projectsIndex); const QModelIndex project1Index = model->index(0, 0, sourceIndex); auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::remove).when(project1).thenReturn(job); // WHEN pages.removeItem(project1Index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove project Project 1: Foo")); } void shouldRemoveContext() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); // Empty sources provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).thenReturn(new FakeJob(this)); // WHEN pages.removeItem(context1Index); // THEN QVERIFY(contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).exactly(1)); } void shouldGetAnErrorMessageWhenRemoveContextFailed() { // GIVEN // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); // Empty sources provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // contexts mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), Domain::ProjectRepository::Ptr(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::remove).when(context1).thenReturn(job); // WHEN pages.removeItem(context1Index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove context context 1: Foo")); } void shouldGetAnErrorMessageWhenUpdateProjectFailed() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source1"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects under the source auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex sourceIndex = model->index(0, 0, projectsIndex); const QModelIndex project1Index = model->index(0, 0, sourceIndex); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::update).when(project1).thenReturn(job); QVERIFY(model->setData(project1Index, "New Project 1")); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify project Project 1: Foo")); } void shouldGetAnErrorMessageWhenUpdateContextFailed() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source1"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects under the source auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), Domain::TaskRepository::Ptr()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::update).when(context1).thenReturn(job); QVERIFY(model->setData(context1Index, "New Context 1")); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify context context 1: Foo")); } void shouldGetAnErrorMessageWhenAssociateProjectFailed() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source1"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects under the source auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // One task (used for dropping later on) Domain::Task::Ptr taskToDrop(new Domain::Task); taskToDrop->setTitle(QStringLiteral("taskDropped")); Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex projectsIndex = model->index(2, 0); const QModelIndex sourceIndex = model->index(0, 0, projectsIndex); const QModelIndex project1Index = model->index(0, 0, sourceIndex); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::associate).when(project1, taskToDrop).thenReturn(job); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, project1Index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add taskDropped to project Project 1: Foo")); } void shouldGetAnErrorMessageWhenAssociateContextFailed() { // GIVEN // One selected data source auto source = Domain::DataSource::Ptr::create(); source->setName("source1"); auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); sourceProvider->append(source); // Two projects under the source auto project1 = Domain::Project::Ptr::create(); project1->setName(QStringLiteral("Project 1")); auto project2 = Domain::Project::Ptr::create(); project2->setName(QStringLiteral("Project 2")); auto projectProvider = Domain::QueryResultProvider::Ptr::create(); auto projectResult = Domain::QueryResult::create(projectProvider); projectProvider->append(project1); projectProvider->append(project2); // Two contexts auto context1 = Domain::Context::Ptr::create(); context1->setName(QStringLiteral("context 1")); auto context2 = Domain::Context::Ptr::create(); context2->setName(QStringLiteral("context 2")); auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); contextProvider->append(context1); contextProvider->append(context2); // One task (used for dropping later on) Domain::Task::Ptr taskToDrop(new Domain::Task); taskToDrop->setTitle(QStringLiteral("taskDropped")); Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); dataSourceQueriesMock(&Domain::DataSourceQueries::findProjects).when(source).thenReturn(projectResult); Utils::MockObject projectRepositoryMock; Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; Utils::MockObject taskRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex contextsIndex = model->index(3, 0); const QModelIndex context1Index = model->index(0, 0, contextsIndex); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); contextRepositoryMock(&Domain::ContextRepository::associate).when(context1, taskToDrop).thenReturn(job); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, context1Index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add taskDropped to context context 1: Foo")); } void shouldGetAnErrorMessageWhenDissociateFailed() { // GIVEN // Empty source provider auto sourceProvider = Domain::QueryResultProvider::Ptr::create(); auto sourceResult = Domain::QueryResult::create(sourceProvider); // Empty context provider auto contextProvider = Domain::QueryResultProvider::Ptr::create(); auto contextResult = Domain::QueryResult::create(contextProvider); // One task (used for dropping later on) Domain::Task::Ptr taskToDrop(new Domain::Task); taskToDrop->setTitle(QStringLiteral("taskDropped")); // context mocking Utils::MockObject contextQueriesMock; contextQueriesMock(&Domain::ContextQueries::findAll).when().thenReturn(contextResult); Utils::MockObject contextRepositoryMock; // sources mocking Utils::MockObject dataSourceQueriesMock; dataSourceQueriesMock(&Domain::DataSourceQueries::findAllSelected).when().thenReturn(sourceResult); Utils::MockObject projectRepositoryMock; Utils::MockObject taskRepositoryMock; Presentation::AvailablePagesModel pages(dataSourceQueriesMock.getInstance(), Domain::ProjectQueries::Ptr(), projectRepositoryMock.getInstance(), contextQueriesMock.getInstance(), contextRepositoryMock.getInstance(), Domain::TaskQueries::Ptr(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; pages.setErrorHandler(&errorHandler); QAbstractItemModel *model = pages.pageListModel(); const QModelIndex inboxIndex = model->index(0, 0); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); projectRepositoryMock(&Domain::ProjectRepository::dissociate).when(taskToDrop).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::dissociateAll).when(taskToDrop).thenReturn(new FakeJob(this)); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << taskToDrop)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, inboxIndex); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move taskDropped to Inbox: Foo")); } }; ZANSHIN_TEST_MAIN(AvailablePagesModelTest) #include "availablepagesmodeltest.moc" diff --git a/tests/units/presentation/taskinboxpagemodeltest.cpp b/tests/units/presentation/inboxpagemodeltest.cpp similarity index 96% rename from tests/units/presentation/taskinboxpagemodeltest.cpp rename to tests/units/presentation/inboxpagemodeltest.cpp index 6dc4e255..acbea98a 100644 --- a/tests/units/presentation/taskinboxpagemodeltest.cpp +++ b/tests/units/presentation/inboxpagemodeltest.cpp @@ -1,550 +1,550 @@ /* 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 #include #include "utils/mockobject.h" #include "domain/taskqueries.h" #include "domain/taskrepository.h" -#include "presentation/taskinboxpagemodel.h" +#include "presentation/inboxpagemodel.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) override { m_message = message; } QString m_message; }; -class TaskInboxPageModelTest : public QObject +class InboxPageModelTest : public QObject { Q_OBJECT private slots: void shouldListInboxInCentralListModel() { // GIVEN // One task auto rootTask = Domain::Task::Ptr::create(); rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); // One task under the root task auto childTask = Domain::Task::Ptr::create(); childTask->setTitle(QStringLiteral("childTask")); childTask->setDone(true); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN QAbstractItemModel *model = inbox.centralListModel(); // THEN const QModelIndex rootTaskIndex = model->index(0, 0); const QModelIndex childTaskIndex = model->index(0, 0, rootTaskIndex); QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(rootTaskIndex), 1); QCOMPARE(model->rowCount(childTaskIndex), 0); const Qt::ItemFlags defaultFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; QCOMPARE(model->flags(rootTaskIndex), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->flags(childTaskIndex), defaultFlags | Qt::ItemIsUserCheckable | Qt::ItemIsDropEnabled); QCOMPARE(model->data(rootTaskIndex).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex).toString(), childTask->title()); QCOMPARE(model->data(rootTaskIndex, Qt::EditRole).toString(), rootTask->title()); QCOMPARE(model->data(childTaskIndex, Qt::EditRole).toString(), childTask->title()); QVERIFY(model->data(rootTaskIndex, Qt::CheckStateRole).isValid()); QVERIFY(model->data(childTaskIndex, Qt::CheckStateRole).isValid()); QCOMPARE(model->data(rootTaskIndex, Qt::CheckStateRole).toBool(), rootTask->isDone()); QCOMPARE(model->data(childTaskIndex, Qt::CheckStateRole).toBool(), childTask->isDone()); // WHEN taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).thenReturn(new FakeJob(this)); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); QVERIFY(model->setData(childTaskIndex, "newChildTask")); QVERIFY(model->setData(rootTaskIndex, Qt::Checked, Qt::CheckStateRole)); QVERIFY(model->setData(childTaskIndex, Qt::Unchecked, Qt::CheckStateRole)); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).exactly(2)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask).exactly(2)); QCOMPARE(rootTask->title(), QStringLiteral("newRootTask")); QCOMPARE(childTask->title(), QStringLiteral("newChildTask")); QCOMPARE(rootTask->isDone(), true); QCOMPARE(childTask->isDone(), false); // WHEN auto data = std::unique_ptr(model->mimeData(QModelIndexList() << childTaskIndex)); // THEN QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); QCOMPARE(data->property("objects").value(), Domain::Task::List() << childTask); // WHEN auto childTask2 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask2)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask2).exactly(1)); // WHEN auto childTask3 = Domain::Task::Ptr::create(); auto childTask4 = Domain::Task::Ptr::create(); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(new FakeJob(this)); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); data.reset(new QMimeData); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask3 << childTask4)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldAddTasksInInbox() { // GIVEN // ... in fact we won't list any model Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::create).when(any()).thenReturn(new FakeJob(this)); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN auto title = QStringLiteral("New task"); auto task = inbox.addItem(title); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::create).when(any()).exactly(1)); QVERIFY(task); QCOMPARE(task->title(), title); } void shouldAddChildTask() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .thenReturn(new FakeJob(this)); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const auto title = QStringLiteral("New task"); const auto parentIndex = inbox.centralListModel()->index(0, 0); const auto createdTask = inbox.addItem(title, parentIndex); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any(), any()) .exactly(1)); QVERIFY(createdTask); QCOMPARE(createdTask->title(), title); } void shouldGetAnErrorMessageWhenAddTaskFailed() { // GIVEN // ... in fact we won't list any model Utils::MockObject taskQueriesMock; // We'll gladly create a task though Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::create).when(any()).thenReturn(job); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN inbox.addItem(QStringLiteral("New task")); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add task New task in Inbox: Foo")); } void shouldDeleteItems() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(new FakeJob(this)); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenDeleteItemsFailed() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); task2->setTitle(QStringLiteral("task2")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(task1); inboxProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::remove).when(task2).thenReturn(job); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.removeItem(index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot remove task task2 from Inbox: Foo")); } void shouldPromoteItem() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(task1); taskProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(new FakeJob(this)); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.promoteItem(index); // THEN QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).exactly(1)); } void shouldGetAnErrorMessageWhenPromoteItemFailed() { // GIVEN // Two tasks auto task1 = Domain::Task::Ptr::create(); auto task2 = Domain::Task::Ptr::create(); task2->setTitle(QStringLiteral("task2")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(task1); inboxProvider->append(task2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task2).thenReturn(job); - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN const QModelIndex index = inbox.centralListModel()->index(1, 0); inbox.promoteItem(index); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot promote task task2 to be a project: Foo")); } void shouldGetAnErrorMessageWhenUpdateTaskFailed() { // GIVEN // One task auto rootTask = Domain::Task::Ptr::create(); rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::update).when(rootTask).thenReturn(job); QVERIFY(model->setData(rootTaskIndex, "newRootTask")); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task rootTask in Inbox: Foo")); } void shouldGetAnErrorMessageWhenAssociateTaskFailed() { // GIVEN // One task auto rootTask = Domain::Task::Ptr::create(); rootTask->setTitle(QStringLiteral("rootTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(rootTask); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(rootTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(any()).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex rootTaskIndex = model->index(0, 0); FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto childTask3 = Domain::Task::Ptr::create(); childTask3->setTitle(QStringLiteral("childTask3")); auto childTask4 = Domain::Task::Ptr::create(); auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask3).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).thenReturn(new FakeJob(this)); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask3 << childTask4)); model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, rootTaskIndex); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move task childTask3 as sub-task of rootTask: Foo")); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(rootTask, childTask4).exactly(1)); } void shouldDeparentWhenNoErrorHappens() { // GIVEN // One task, top level auto topLevelTask = Domain::Task::Ptr::create(); topLevelTask->setTitle(QStringLiteral("topLevelTask")); auto inboxProvider = Domain::QueryResultProvider::Ptr::create(); auto inboxResult = Domain::QueryResult::create(inboxProvider); inboxProvider->append(topLevelTask); // Two tasks under the top level task auto childTask = Domain::Task::Ptr::create(); childTask->setTitle(QStringLiteral("childTask")); childTask->setDone(true); auto childTask2 = Domain::Task::Ptr::create(); childTask2->setTitle(QStringLiteral("childTask2")); childTask2->setDone(false); auto taskProvider = Domain::QueryResultProvider::Ptr::create(); auto taskResult = Domain::QueryResult::create(taskProvider); taskProvider->append(childTask); taskProvider->append(childTask2); Utils::MockObject taskQueriesMock; taskQueriesMock(&Domain::TaskQueries::findInboxTopLevel).when().thenReturn(inboxResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(topLevelTask).thenReturn(taskResult); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask2).thenReturn(Domain::QueryResult::Ptr()); taskQueriesMock(&Domain::TaskQueries::findDataSource).when(childTask).thenReturn(Domain::QueryResult::Ptr()); Utils::MockObject taskRepositoryMock; - Presentation::TaskInboxPageModel inbox(taskQueriesMock.getInstance(), + Presentation::InboxPageModel inbox(taskQueriesMock.getInstance(), taskRepositoryMock.getInstance()); QAbstractItemModel *model = inbox.centralListModel(); const QModelIndex emptyPartModel = QModelIndex(); // model root, drop on the empty part is equivalent FakeErrorHandler errorHandler; inbox.setErrorHandler(&errorHandler); // WHEN auto job = new FakeJob(this); job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo")); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).thenReturn(job); taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).thenReturn(new FakeJob(this)); auto data = std::make_unique(); data->setData(QStringLiteral("application/x-zanshin-object"), "object"); data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask << childTask2)); // both will be DnD on the empty part model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, emptyPartModel); // THEN QTest::qWait(150); QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot deparent task childTask from its parent: Foo")); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).exactly(1)); QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).exactly(1)); } }; -ZANSHIN_TEST_MAIN(TaskInboxPageModelTest) +ZANSHIN_TEST_MAIN(InboxPageModelTest) -#include "taskinboxpagemodeltest.moc" +#include "inboxpagemodeltest.moc"