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