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

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
0003    SPDX-FileCopyrightText: 2014 RĂ©mi Benoit <r3m1.benoit@gmail.com>
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 
0008 #include <testlib/qtest_zanshin.h>
0009 
0010 #include <memory>
0011 
0012 #include <QMimeData>
0013 
0014 #include "utils/mockobject.h"
0015 
0016 #include "domain/context.h"
0017 #include "domain/task.h"
0018 
0019 #include "domain/contextqueries.h"
0020 #include "domain/contextrepository.h"
0021 #include "domain/taskqueries.h"
0022 #include "domain/taskrepository.h"
0023 
0024 #include "presentation/contextpagemodel.h"
0025 #include "presentation/errorhandler.h"
0026 
0027 #include "testlib/fakejob.h"
0028 
0029 using namespace mockitopp;
0030 using namespace mockitopp::matcher;
0031 
0032 class FakeErrorHandler : public Presentation::ErrorHandler
0033 {
0034 public:
0035     void doDisplayMessage(const QString &message) override
0036     {
0037         m_message = message;
0038     }
0039 
0040     QString m_message;
0041 };
0042 
0043 class ContextPageModelTest : public QObject
0044 {
0045     Q_OBJECT
0046 
0047 private slots:
0048     void shouldListAssociatedTaskInContextCentralListView() {
0049         // GIVEN
0050 
0051         // A context
0052         auto context = Domain::Context::Ptr::create();
0053 
0054         // Three tasks
0055         auto task1 = Domain::Task::Ptr::create();
0056         task1->setTitle(QStringLiteral("task1"));
0057         auto task2 = Domain::Task::Ptr::create();
0058         task2->setTitle(QStringLiteral("task2"));
0059         auto task3 = Domain::Task::Ptr::create();
0060         task3->setTitle(QStringLiteral("task3"));
0061 
0062         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0063         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0064         taskProvider->append(task1);
0065         taskProvider->append(task2);
0066         taskProvider->append(task3);
0067 
0068         // Two tasks under the task1
0069         auto childTask11 = Domain::Task::Ptr::create();
0070         childTask11->setTitle(QStringLiteral("childTask11"));
0071         auto childTask12 = Domain::Task::Ptr::create();
0072         childTask12->setTitle(QStringLiteral("childTask12"));
0073         auto childTaskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0074         auto childTaskResult = Domain::QueryResult<Domain::Task::Ptr>::create(childTaskProvider);
0075         taskProvider->append(childTask12);
0076         childTaskProvider->append(childTask11);
0077         childTaskProvider->append(childTask12);
0078 
0079         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0080         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0081 
0082         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0083         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task1).thenReturn(childTaskResult);
0084         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task2).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0085         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task3).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0086         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask11).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0087         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask12).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0088         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0089 
0090         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0091         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0092 
0093         Presentation::ContextPageModel page(context,
0094                                             contextQueriesMock.getInstance(),
0095                                             contextRepositoryMock.getInstance(),
0096                                             taskQueriesMock.getInstance(),
0097                                             taskRepositoryMock.getInstance());
0098 
0099         // WHEN
0100         QAbstractItemModel *model = page.centralListModel();
0101 
0102         // THEN
0103         const QModelIndex task1Index = model->index(0, 0);
0104         const QModelIndex task2Index = model->index(1, 0);
0105         const QModelIndex task3Index = model->index(2, 0);
0106         const QModelIndex taskChildTask12Index = model->index(3, 0);
0107 
0108         const QModelIndex childTask11Index = model->index(0, 0, task1Index);
0109         const QModelIndex childTask12Index = model->index(1, 0, task1Index);
0110 
0111         QCOMPARE(page.context(), context);
0112 
0113         QCOMPARE(model->rowCount(), 4);
0114         QCOMPARE(model->rowCount(task1Index), 2);
0115         QCOMPARE(model->rowCount(task2Index), 0);
0116         QCOMPARE(model->rowCount(task3Index), 0);
0117         QCOMPARE(model->rowCount(taskChildTask12Index), 0);
0118 
0119         QVERIFY(childTask11Index.isValid());
0120         QVERIFY(childTask12Index.isValid());
0121         QCOMPARE(model->rowCount(childTask11Index), 0);
0122         QCOMPARE(model->rowCount(childTask12Index), 0);
0123 
0124         const Qt::ItemFlags taskFlags = Qt::ItemIsSelectable
0125                                       | Qt::ItemIsEnabled
0126                                       | Qt::ItemIsEditable
0127                                       | Qt::ItemIsDragEnabled
0128                                       | Qt::ItemIsUserCheckable
0129                                       | Qt::ItemIsDropEnabled;
0130         QCOMPARE(model->flags(task1Index), taskFlags);
0131         QCOMPARE(model->flags(childTask11Index), taskFlags);
0132         QCOMPARE(model->flags(childTask12Index), taskFlags);
0133         QCOMPARE(model->flags(task2Index), taskFlags);
0134         QCOMPARE(model->flags(task3Index), taskFlags);
0135         QCOMPARE(model->flags(taskChildTask12Index), taskFlags);
0136 
0137         QCOMPARE(model->data(task1Index).toString(), task1->title());
0138         QCOMPARE(model->data(childTask11Index).toString(), childTask11->title());
0139         QCOMPARE(model->data(childTask12Index).toString(), childTask12->title());
0140         QCOMPARE(model->data(task2Index).toString(), task2->title());
0141         QCOMPARE(model->data(task3Index).toString(), task3->title());
0142         QCOMPARE(model->data(taskChildTask12Index).toString(), childTask12->title());
0143 
0144         QCOMPARE(model->data(task1Index, Qt::EditRole).toString(), task1->title());
0145         QCOMPARE(model->data(childTask11Index, Qt::EditRole).toString(), childTask11->title());
0146         QCOMPARE(model->data(childTask12Index, Qt::EditRole).toString(), childTask12->title());
0147         QCOMPARE(model->data(task2Index, Qt::EditRole).toString(), task2->title());
0148         QCOMPARE(model->data(task3Index, Qt::EditRole).toString(), task3->title());
0149         QCOMPARE(model->data(taskChildTask12Index, Qt::EditRole).toString(), childTask12->title());
0150 
0151         QVERIFY(model->data(task1Index, Qt::CheckStateRole).isValid());
0152         QVERIFY(model->data(childTask11Index, Qt::CheckStateRole).isValid());
0153         QVERIFY(model->data(childTask12Index, Qt::CheckStateRole).isValid());
0154         QVERIFY(model->data(task2Index, Qt::CheckStateRole).isValid());
0155         QVERIFY(model->data(task3Index, Qt::CheckStateRole).isValid());
0156         QVERIFY(model->data(taskChildTask12Index, Qt::CheckStateRole).isValid());
0157 
0158         QCOMPARE(model->data(task1Index, Qt::CheckStateRole).toBool(), task1->isDone());
0159         QCOMPARE(model->data(childTask11Index, Qt::CheckStateRole).toBool(), childTask11->isDone());
0160         QCOMPARE(model->data(childTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone());
0161         QCOMPARE(model->data(task2Index, Qt::CheckStateRole).toBool(), task2->isDone());
0162         QCOMPARE(model->data(task3Index, Qt::CheckStateRole).toBool(), task3->isDone());
0163         QCOMPARE(model->data(taskChildTask12Index, Qt::CheckStateRole).toBool(), childTask12->isDone());
0164 
0165         // WHEN
0166         taskRepositoryMock(&Domain::TaskRepository::update).when(task1).thenReturn(new FakeJob(this));
0167         taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).thenReturn(new FakeJob(this));
0168         taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).thenReturn(new FakeJob(this));
0169         taskRepositoryMock(&Domain::TaskRepository::update).when(task2).thenReturn(new FakeJob(this));
0170         taskRepositoryMock(&Domain::TaskRepository::update).when(task3).thenReturn(new FakeJob(this));
0171 
0172         QVERIFY(model->setData(task1Index, "newTask1"));
0173         QVERIFY(model->setData(childTask11Index, "newChildTask11"));
0174         QVERIFY(model->setData(task2Index, "newTask2"));
0175         QVERIFY(model->setData(task3Index, "newTask3"));
0176         QVERIFY(model->setData(taskChildTask12Index, "newChildTask12"));
0177 
0178         QVERIFY(model->setData(task1Index, Qt::Unchecked, Qt::CheckStateRole));
0179         QVERIFY(model->setData(childTask11Index, Qt::Unchecked, Qt::CheckStateRole));
0180         QVERIFY(model->setData(task2Index, Qt::Checked, Qt::CheckStateRole));
0181         QVERIFY(model->setData(task3Index, Qt::Unchecked, Qt::CheckStateRole));
0182         QVERIFY(model->setData(taskChildTask12Index, Qt::Checked, Qt::CheckStateRole));
0183 
0184         // THEN
0185         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task1).exactly(2));
0186         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask11).exactly(2));
0187         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(childTask12).exactly(2));
0188         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task2).exactly(2));
0189         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task3).exactly(2));
0190 
0191         QCOMPARE(task1->title(), QStringLiteral("newTask1"));
0192         QCOMPARE(childTask11->title(), QStringLiteral("newChildTask11"));
0193         QCOMPARE(childTask12->title(), QStringLiteral("newChildTask12"));
0194         QCOMPARE(task2->title(), QStringLiteral("newTask2"));
0195         QCOMPARE(task3->title(), QStringLiteral("newTask3"));
0196 
0197         QCOMPARE(task1->isDone(), false);
0198         QCOMPARE(childTask11->isDone(), false);
0199         QCOMPARE(childTask12->isDone(), true);
0200         QCOMPARE(task2->isDone(), true);
0201         QCOMPARE(task3->isDone(), false);
0202 
0203         // WHEN
0204         QVERIFY(!model->setData(task1Index, QVariant(), Qt::WhatsThisRole));
0205         QVERIFY(!model->setData(task1Index, QVariant(), Qt::ForegroundRole));
0206         QVERIFY(!model->setData(task1Index, QVariant(), Qt::InitialSortOrderRole));
0207 
0208         // THEN
0209         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::update).when(task1).exactly(2));
0210 
0211         QCOMPARE(task1->title(), QStringLiteral("newTask1"));
0212         QCOMPARE(task2->title(), QStringLiteral("newTask2"));
0213         // WHEN a task is dragged
0214         auto data = std::unique_ptr<QMimeData>(model->mimeData(QModelIndexList() << task2Index));
0215 
0216         // THEN
0217         QVERIFY(data->hasFormat(QStringLiteral("application/x-zanshin-object")));
0218         QCOMPARE(data->property("objects").value<Domain::Task::List>(),
0219                  Domain::Task::List() << task2);
0220 
0221         // WHEN a task is dropped
0222         auto childTask2 = Domain::Task::Ptr::create();
0223         taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask2).thenReturn(new FakeJob(this));
0224         data.reset(new QMimeData);
0225         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0226         data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask2));
0227         model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, task1Index);
0228 
0229         // THEN
0230         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask2).exactly(1));
0231 
0232         // WHEN two tasks are dropped
0233         auto childTask3 = Domain::Task::Ptr::create();
0234         auto childTask4 = Domain::Task::Ptr::create();
0235         taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask3).thenReturn(new FakeJob(this));
0236         taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask4).thenReturn(new FakeJob(this));
0237         data.reset(new QMimeData);
0238         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0239         data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask3 << childTask4));
0240         model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, task1Index);
0241 
0242         // THEN
0243         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask3).exactly(1));
0244         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::associate).when(task1, childTask4).exactly(1));
0245     }
0246 
0247     void shouldAddTasksInContext()
0248     {
0249         // GIVEN
0250 
0251         // One Context
0252         auto context = Domain::Context::Ptr::create();
0253 
0254         // ... in fact we won't list any model
0255         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0256         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0257         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0258 
0259         // We'll gladly create a task though
0260         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0261         taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any<Domain::Task::Ptr>(),
0262                                                                           any<Domain::Context::Ptr>())
0263                                                                     .thenReturn(new FakeJob(this));
0264 
0265         Presentation::ContextPageModel page(context,
0266                                             contextQueriesMock.getInstance(),
0267                                             contextRepositoryMock.getInstance(),
0268                                             taskQueriesMock.getInstance(),
0269                                             taskRepositoryMock.getInstance());
0270 
0271         // WHEN
0272          auto title = QStringLiteral("New task");
0273          auto task = page.addItem(title);
0274 
0275          // THEN
0276          QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any<Domain::Task::Ptr>(),
0277                                                                                         any<Domain::Context::Ptr>())
0278                                                                                     .exactly(1));
0279          QVERIFY(task);
0280          QCOMPARE(task->title(), title);
0281     }
0282 
0283     void shouldAddChildTask()
0284     {
0285         // GIVEN
0286 
0287         // One Context
0288         auto context = Domain::Context::Ptr::create();
0289 
0290         // A task
0291         auto task = Domain::Task::Ptr::create();
0292 
0293         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0294         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0295         taskProvider->append(task);
0296 
0297         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0298         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0299 
0300         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0301         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0302 
0303         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0304 
0305         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0306         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult);
0307         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0308 
0309         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0310         taskRepositoryMock(&Domain::TaskRepository::createChild).when(any<Domain::Task::Ptr>(),
0311                                                                       any<Domain::Task::Ptr>())
0312                                                                 .thenReturn(new FakeJob(this));
0313 
0314         Presentation::ContextPageModel page(context,
0315                                             contextQueriesMock.getInstance(),
0316                                             contextRepositoryMock.getInstance(),
0317                                             taskQueriesMock.getInstance(),
0318                                             taskRepositoryMock.getInstance());
0319 
0320         // WHEN
0321         const auto title = QStringLiteral("New task");
0322         const auto parentIndex = page.centralListModel()->index(0, 0);
0323         const auto createdTask = page.addItem(title, parentIndex);
0324 
0325         // THEN
0326         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::createChild).when(any<Domain::Task::Ptr>(),
0327                                                                               any<Domain::Task::Ptr>())
0328                                                                         .exactly(1));
0329         QVERIFY(createdTask);
0330         QCOMPARE(createdTask->title(), title);
0331     }
0332 
0333     void shouldRemoveTopLevelItem()
0334     {
0335         // GIVEN
0336 
0337         // One context
0338         auto context = Domain::Context::Ptr::create();
0339 
0340         // A task
0341         auto task = Domain::Task::Ptr::create();
0342 
0343         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0344         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0345         taskProvider->append(task);
0346 
0347         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0348         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0349 
0350         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0351         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0352 
0353         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0354         contextRepositoryMock(&Domain::ContextRepository::dissociate).when(context, task).thenReturn(new FakeJob(this));
0355 
0356         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0357         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult);
0358         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0359 
0360         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0361 
0362         Presentation::ContextPageModel page(context,
0363                                             contextQueriesMock.getInstance(),
0364                                             contextRepositoryMock.getInstance(),
0365                                             taskQueriesMock.getInstance(),
0366                                             taskRepositoryMock.getInstance());
0367 
0368         // WHEN
0369         const QModelIndex indexTask = page.centralListModel()->index(0, 0);
0370         page.removeItem(indexTask);
0371 
0372         // THEN
0373         QVERIFY(contextRepositoryMock(&Domain::ContextRepository::dissociate).when(context, task).exactly(1));
0374     }
0375 
0376     void shouldRemoveChildItem()
0377     {
0378         // GIVEN
0379 
0380         // One context
0381         auto context = Domain::Context::Ptr::create();
0382 
0383         // A task...
0384         auto task = Domain::Task::Ptr::create();
0385 
0386         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0387         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0388         taskProvider->append(task);
0389 
0390         // ... with a child
0391         auto childTask = Domain::Task::Ptr::create();
0392         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0393         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0394         childProvider->append(childTask);
0395 
0396         auto emptyProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0397         auto emptyResult = Domain::QueryResult<Domain::Task::Ptr>::create(emptyProvider);
0398 
0399         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0400         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0401 
0402         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0403 
0404         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0405         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult);
0406         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(emptyResult);
0407         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0408 
0409         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0410         taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).thenReturn(new FakeJob(this));
0411 
0412         Presentation::ContextPageModel page(context,
0413                                             contextQueriesMock.getInstance(),
0414                                             contextRepositoryMock.getInstance(),
0415                                             taskQueriesMock.getInstance(),
0416                                             taskRepositoryMock.getInstance());
0417 
0418         // WHEN
0419         const auto taskIndex = page.centralListModel()->index(0, 0);
0420         const auto childTaskIndex = page.centralListModel()->index(0, 0, taskIndex);
0421         page.removeItem(childTaskIndex);
0422 
0423         // THEN
0424         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask).exactly(1));
0425     }
0426 
0427     void shouldPromoteItem()
0428     {
0429         // GIVEN
0430 
0431         // One context
0432         auto context = Domain::Context::Ptr::create();
0433 
0434         // A task
0435         auto task = Domain::Task::Ptr::create();
0436 
0437         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0438         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0439         taskProvider->append(task);
0440 
0441         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0442         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0443 
0444         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0445         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0446 
0447         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0448 
0449         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0450         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult);
0451         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0452 
0453         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0454         taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task).thenReturn(new FakeJob(this));
0455 
0456         Presentation::ContextPageModel page(context,
0457                                             contextQueriesMock.getInstance(),
0458                                             contextRepositoryMock.getInstance(),
0459                                             taskQueriesMock.getInstance(),
0460                                             taskRepositoryMock.getInstance());
0461 
0462         // WHEN
0463         const QModelIndex indexTask = page.centralListModel()->index(0, 0);
0464         page.promoteItem(indexTask);
0465 
0466         // THEN
0467         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::promoteToProject).when(task).exactly(1));
0468     }
0469 
0470     void shouldGetAnErrorMessageWhenAddTaskFailed()
0471     {
0472         // GIVEN
0473 
0474         // One Context
0475         auto context = Domain::Context::Ptr::create();
0476         context->setName(QStringLiteral("Context1"));
0477 
0478         // ... in fact we won't list any model
0479         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0480         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0481         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0482 
0483         // We'll gladly create a task though
0484         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0485         auto job = new FakeJob(this);
0486         job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo"));
0487         taskRepositoryMock(&Domain::TaskRepository::createInContext).when(any<Domain::Task::Ptr>(),
0488                                                                           any<Domain::Context::Ptr>())
0489                                                                     .thenReturn(job);
0490 
0491         Presentation::ContextPageModel page(context,
0492                                             contextQueriesMock.getInstance(),
0493                                             contextRepositoryMock.getInstance(),
0494                                             taskQueriesMock.getInstance(),
0495                                             taskRepositoryMock.getInstance());
0496         FakeErrorHandler errorHandler;
0497         page.setErrorHandler(&errorHandler);
0498 
0499         // WHEN
0500         page.addItem(QStringLiteral("New task"));
0501 
0502         // THEN
0503         QTest::qWait(150);
0504         QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot add task New task in context Context1: Foo"));
0505     }
0506 
0507     void shouldGetAnErrorMessageWhenUpdateTaskFailed()
0508     {
0509         // GIVEN
0510 
0511         // A context
0512         auto context = Domain::Context::Ptr::create();
0513         context->setName(QStringLiteral("Context1"));
0514 
0515         // A task
0516         auto task = Domain::Task::Ptr::create();
0517         task->setTitle(QStringLiteral("A task"));
0518 
0519         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0520         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0521         taskProvider->append(task);
0522 
0523         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0524         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0525 
0526         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0527         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0528 
0529         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0530         taskQueriesMock(&Domain::TaskQueries::findChildren).when(task).thenReturn(childResult);
0531         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0532 
0533         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0534         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0535 
0536         Presentation::ContextPageModel page(context,
0537                                             contextQueriesMock.getInstance(),
0538                                             contextRepositoryMock.getInstance(),
0539                                             taskQueriesMock.getInstance(),
0540                                             taskRepositoryMock.getInstance());
0541 
0542         QAbstractItemModel *model = page.centralListModel();
0543         const QModelIndex taskIndex = model->index(0, 0);
0544         FakeErrorHandler errorHandler;
0545         page.setErrorHandler(&errorHandler);
0546 
0547         // WHEN
0548         auto job = new FakeJob(this);
0549         job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo"));
0550         taskRepositoryMock(&Domain::TaskRepository::update).when(task).thenReturn(job);
0551 
0552         QVERIFY(model->setData(taskIndex, "newTask"));
0553 
0554         // THEN
0555         QTest::qWait(150);
0556         QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot modify task A task in context Context1: Foo"));
0557     }
0558 
0559     void shouldGetAnErrorMessageWhenAssociateTaskFailed()
0560     {
0561         // GIVEN
0562 
0563         // A context
0564         auto context = Domain::Context::Ptr::create();
0565         context->setName(QStringLiteral("Context1"));
0566 
0567         // A parent task and a child task
0568         auto parentTask = Domain::Task::Ptr::create();
0569         parentTask->setTitle(QStringLiteral("A parent task"));
0570         auto childTask = Domain::Task::Ptr::create();
0571         childTask->setTitle(QStringLiteral("A child task"));
0572 
0573         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0574         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0575         taskProvider->append(parentTask);
0576         taskProvider->append(childTask);
0577 
0578         auto childProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0579         auto childResult = Domain::QueryResult<Domain::Task::Ptr>::create(childProvider);
0580 
0581         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0582         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(taskResult);
0583 
0584         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0585 
0586         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0587         taskQueriesMock(&Domain::TaskQueries::findChildren).when(parentTask).thenReturn(childResult);
0588         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask).thenReturn(childResult);
0589         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0590 
0591         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0592 
0593         Presentation::ContextPageModel page(context,
0594                                             contextQueriesMock.getInstance(),
0595                                             contextRepositoryMock.getInstance(),
0596                                             taskQueriesMock.getInstance(),
0597                                             taskRepositoryMock.getInstance());
0598 
0599         // WHEN
0600         QAbstractItemModel *model = page.centralListModel();
0601         const QModelIndex parentTaskIndex = model->index(0, 0);
0602         FakeErrorHandler errorHandler;
0603         page.setErrorHandler(&errorHandler);
0604 
0605         // WHEN a task is dropped
0606         auto childTask2 = Domain::Task::Ptr::create();
0607         childTask2->setTitle(QStringLiteral("childTask2"));
0608         auto job = new FakeJob(this);
0609         job->setExpectedError(KJob::KilledJobError, QStringLiteral("Foo"));
0610         taskRepositoryMock(&Domain::TaskRepository::associate).when(parentTask, childTask2).thenReturn(job);
0611         auto data = std::make_unique<QMimeData>();
0612         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0613         data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask2));
0614         model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, parentTaskIndex);
0615 
0616         // THEN
0617         QTest::qWait(150);
0618         QCOMPARE(errorHandler.m_message, QStringLiteral("Cannot move task childTask2 as sub-task of A parent task: Foo"));
0619     }
0620 
0621     void shouldAssociateToContextWithNoParentWhenDroppingOnEmptyArea()
0622     {
0623         // GIVEN
0624 
0625         // One context
0626         auto context = Domain::Context::Ptr::create();
0627         context->setName(QStringLiteral("Context"));
0628 
0629         // One top level task
0630         auto topLevelTask = Domain::Task::Ptr::create();
0631         topLevelTask->setTitle(QStringLiteral("rootTask"));
0632         auto topLevelProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0633         auto topLevelResult = Domain::QueryResult<Domain::Task::Ptr>::create(topLevelProvider);
0634         topLevelProvider->append(topLevelTask);
0635 
0636         // Two tasks under the top level task
0637         auto childTask1 = Domain::Task::Ptr::create();
0638         childTask1->setTitle(QStringLiteral("childTask1"));
0639         childTask1->setDone(true);
0640         auto childTask2 = Domain::Task::Ptr::create();
0641         childTask2->setTitle(QStringLiteral("childTask2"));
0642         childTask2->setDone(false);
0643         auto taskProvider = Domain::QueryResultProvider<Domain::Task::Ptr>::Ptr::create();
0644         auto taskResult = Domain::QueryResult<Domain::Task::Ptr>::create(taskProvider);
0645         taskProvider->append(childTask1);
0646         taskProvider->append(childTask2);
0647 
0648         Utils::MockObject<Domain::ContextQueries> contextQueriesMock;
0649         contextQueriesMock(&Domain::ContextQueries::findTopLevelTasks).when(context).thenReturn(topLevelResult);
0650 
0651         Utils::MockObject<Domain::ContextRepository> contextRepositoryMock;
0652 
0653         Utils::MockObject<Domain::TaskQueries> taskQueriesMock;
0654         taskQueriesMock(&Domain::TaskQueries::findChildren).when(topLevelTask).thenReturn(taskResult);
0655         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask1).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0656         taskQueriesMock(&Domain::TaskQueries::findChildren).when(childTask2).thenReturn(Domain::QueryResult<Domain::Task::Ptr>::Ptr());
0657         taskQueriesMock(&Domain::TaskQueries::findProject).when(any<Domain::Task::Ptr>()).thenReturn(Domain::QueryResult<Domain::Project::Ptr>::Ptr());
0658 
0659         Utils::MockObject<Domain::TaskRepository> taskRepositoryMock;
0660 
0661         Presentation::ContextPageModel page(context,
0662                                             contextQueriesMock.getInstance(),
0663                                             contextRepositoryMock.getInstance(),
0664                                             taskQueriesMock.getInstance(),
0665                                             taskRepositoryMock.getInstance());
0666 
0667         auto model = page.centralListModel();
0668 
0669         // WHEN
0670         taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask1).thenReturn(new FakeJob(this));
0671         taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).thenReturn(new FakeJob(this));
0672         contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask1).thenReturn(new FakeJob(this));
0673         contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask2).thenReturn(new FakeJob(this));
0674 
0675         auto data = std::make_unique<QMimeData>();
0676         data->setData(QStringLiteral("application/x-zanshin-object"), "object");
0677         data->setProperty("objects", QVariant::fromValue(Domain::Task::List() << childTask1 << childTask2)); // both will be DnD on the empty part
0678         model->dropMimeData(data.get(), Qt::MoveAction, -1, -1, QModelIndex());
0679 
0680         // THEN
0681         QTest::qWait(150);
0682         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask1).exactly(1));
0683         QVERIFY(taskRepositoryMock(&Domain::TaskRepository::dissociate).when(childTask2).exactly(1));
0684         QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask1).exactly(1));
0685         QVERIFY(contextRepositoryMock(&Domain::ContextRepository::associate).when(context, childTask2).exactly(1));
0686     }
0687 };
0688 
0689 ZANSHIN_TEST_MAIN(ContextPageModelTest)
0690 
0691 #include "contextpagemodeltest.moc"