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"