File indexing completed on 2025-01-19 04:56:59
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_gui_zanshin.h> 0008 0009 #include <QMimeData> 0010 #include <QStandardItemModel> 0011 #include <QStringListModel> 0012 #include <QTreeView> 0013 #include <QWidgetAction> 0014 0015 #include <algorithm> 0016 0017 #include "utils/mem_fn.h" 0018 0019 #include "domain/task.h" 0020 0021 #include "presentation/taskfilterproxymodel.h" 0022 #include "presentation/querytreemodelbase.h" 0023 #include "presentation/runningtaskmodelinterface.h" 0024 0025 #include "widgets/applicationcomponents.h" 0026 #include "widgets/availablepagesview.h" 0027 #include "widgets/availablesourcesview.h" 0028 #include "widgets/editorview.h" 0029 #include "widgets/filterwidget.h" 0030 #include "widgets/pageview.h" 0031 #include "widgets/pageviewerrorhandler.h" 0032 #include "widgets/quickselectdialog.h" 0033 #include "widgets/runningtaskwidget.h" 0034 0035 0036 class CustomModelStub : public QStandardItemModel 0037 { 0038 Q_OBJECT 0039 0040 QMimeData *mimeData(const QModelIndexList &indexes) const override 0041 { 0042 QStringList dataString; 0043 std::transform(indexes.begin(), indexes.end(), 0044 std::back_inserter(dataString), 0045 [] (const QModelIndex &index) { 0046 return index.data().toString(); 0047 }); 0048 0049 auto data = new QMimeData; 0050 data->setData(QStringLiteral("application/x-zanshin-object"), "object"); 0051 data->setProperty("objects", QVariant::fromValue(dataString)); 0052 0053 return data; 0054 } 0055 0056 bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &destination) override 0057 { 0058 Q_UNUSED(action); 0059 0060 Q_ASSERT(row == -1); 0061 Q_ASSERT(column == -1); 0062 Q_ASSERT(destination.isValid()); 0063 Q_ASSERT(data->hasFormat(QStringLiteral("application/x-zanshin-object"))); 0064 0065 auto dataString = data->property("objects").toStringList(); 0066 Q_ASSERT(!dataString.isEmpty()); 0067 0068 droppedItemDataString = dataString; 0069 dropDestination = destination.data().toString(); 0070 0071 return true; 0072 } 0073 0074 public: 0075 QStringList droppedItemDataString; 0076 QString dropDestination; 0077 }; 0078 0079 class ApplicationModelStub : public QObject 0080 { 0081 Q_OBJECT 0082 Q_PROPERTY(QObject* currentPage READ currentPage WRITE setCurrentPage) 0083 public: 0084 typedef QSharedPointer<ApplicationModelStub> Ptr; 0085 0086 explicit ApplicationModelStub(QObject *parent = nullptr) 0087 : QObject(parent), m_currentPage(nullptr) {} 0088 0089 QObject *currentPage() 0090 { 0091 return m_currentPage; 0092 } 0093 0094 void setCurrentPage(QObject *page) 0095 { 0096 if (page == m_currentPage) 0097 return; 0098 0099 m_currentPage = page; 0100 emit currentPageChanged(m_currentPage); 0101 } 0102 0103 signals: 0104 void currentPageChanged(QObject *page); 0105 0106 private: 0107 QObject *m_currentPage; 0108 }; 0109 0110 class AvailablePagesModelStub : public QObject 0111 { 0112 Q_OBJECT 0113 Q_PROPERTY(QAbstractItemModel* pageListModel READ pageListModel) 0114 public: 0115 explicit AvailablePagesModelStub(QObject *parent = nullptr) 0116 : QObject(parent) 0117 { 0118 QStandardItem *inbox = new QStandardItem; 0119 inbox->setData("Inbox", Qt::DisplayRole); 0120 itemModel.appendRow(inbox); 0121 0122 QStandardItem *project = new QStandardItem; 0123 project->setData("Project", Qt::DisplayRole); 0124 itemModel.appendRow(project); 0125 } 0126 0127 QAbstractItemModel *pageListModel() 0128 { 0129 return &itemModel; 0130 } 0131 0132 Q_SCRIPTABLE QObject *createPageForIndex(const QModelIndex &index) 0133 { 0134 auto page = new QObject(this); 0135 auto model = new QStringListModel(page); 0136 model->setStringList(QStringList() << QStringLiteral("Items") << QStringLiteral("from") << index.data().toString()); 0137 page->setProperty("centralListModel", 0138 QVariant::fromValue<QAbstractItemModel*>(model)); 0139 createdPages << page; 0140 return page; 0141 } 0142 0143 public: 0144 QList<QObject*> createdPages; 0145 CustomModelStub itemModel; 0146 }; 0147 0148 class PageModelStub : public QObject 0149 { 0150 Q_OBJECT 0151 Q_PROPERTY(QAbstractItemModel* centralListModel READ centralListModel) 0152 public: 0153 QAbstractItemModel *centralListModel() 0154 { 0155 return &itemModel; 0156 } 0157 0158 void addTask(const QString &title) 0159 { 0160 auto task = Domain::Task::Ptr::create(); 0161 task->setTitle(title); 0162 addTask(task); 0163 } 0164 0165 void addTask(const Domain::Task::Ptr &task) 0166 { 0167 QStandardItem *item = new QStandardItem; 0168 item->setData(QVariant::fromValue(task), Presentation::QueryTreeModelBase::ObjectRole); 0169 item->setData(task->title(), Qt::DisplayRole); 0170 itemModel.appendRow(item); 0171 } 0172 0173 Domain::Task::Ptr itemAtRow(int row) const 0174 { 0175 return itemModel.index(row, 0).data(Presentation::QueryTreeModelBase::ObjectRole) 0176 .value<Domain::Task::Ptr>(); 0177 } 0178 0179 QModelIndexList selectedIndexes() const 0180 { 0181 return selectedItems; 0182 } 0183 0184 public: 0185 QModelIndexList selectedItems; 0186 CustomModelStub itemModel; 0187 }; 0188 0189 class EditorModelStub : public QObject 0190 { 0191 Q_OBJECT 0192 public: 0193 explicit EditorModelStub(QObject *parent = nullptr) 0194 : QObject(parent) 0195 { 0196 } 0197 0198 void setPropertyAndSignal(const QByteArray &name, const QVariant &value) 0199 { 0200 if (property(name) == value) 0201 return; 0202 0203 setProperty(name, value); 0204 if (name == "text") 0205 emit textChanged(value.toString()); 0206 else if (name == "title") 0207 emit titleChanged(value.toString()); 0208 else if (name == "done") 0209 emit doneChanged(value.toBool()); 0210 else if (name == "startDate") 0211 emit startDateChanged(value.toDate()); 0212 else if (name == "dueDate") 0213 emit dueDateChanged(value.toDate()); 0214 else 0215 qFatal("Unsupported property %s", name.constData()); 0216 } 0217 0218 public slots: 0219 void setTitle(const QString &title) { setPropertyAndSignal("title", title); } 0220 void setText(const QString &text) { setPropertyAndSignal("text", text); } 0221 void setDone(bool done) { setPropertyAndSignal("done", done); } 0222 void setStartDate(const QDate &start) { setPropertyAndSignal("startDate", start); } 0223 void setDueDate(const QDate &due) { setPropertyAndSignal("dueDate", due); } 0224 0225 signals: 0226 void textChanged(const QString &text); 0227 void titleChanged(const QString &title); 0228 void doneChanged(bool done); 0229 void startDateChanged(const QDate &date); 0230 void dueDateChanged(const QDate &due); 0231 }; 0232 0233 class RunningTaskModelStub : public Presentation::RunningTaskModelInterface 0234 { 0235 Q_OBJECT 0236 public: 0237 explicit RunningTaskModelStub(QObject *parent = nullptr) 0238 : Presentation::RunningTaskModelInterface(parent) 0239 { 0240 } 0241 0242 Domain::Task::Ptr runningTask() const override { return {}; } 0243 void setRunningTask(const Domain::Task::Ptr &) override {} 0244 void taskDeleted(const Domain::Task::Ptr &) override {} 0245 void stopTask() override {} 0246 void doneTask() override {} 0247 }; 0248 0249 class QuickSelectDialogStub : public Widgets::QuickSelectDialogInterface 0250 { 0251 public: 0252 typedef QSharedPointer<QuickSelectDialogStub> Ptr; 0253 0254 explicit QuickSelectDialogStub() 0255 : parent(nullptr), 0256 execCount(0), 0257 itemModel(nullptr) 0258 { 0259 } 0260 0261 int exec() override 0262 { 0263 execCount++; 0264 return QDialog::Accepted; 0265 } 0266 0267 void setModel(QAbstractItemModel *model) override 0268 { 0269 itemModel = model; 0270 } 0271 0272 QPersistentModelIndex selectedIndex() const override 0273 { 0274 return index; 0275 } 0276 0277 QWidget *parent; 0278 int execCount; 0279 QAbstractItemModel *itemModel; 0280 QPersistentModelIndex index; 0281 }; 0282 0283 class ApplicationComponentsTest : public QObject 0284 { 0285 Q_OBJECT 0286 public: 0287 explicit ApplicationComponentsTest(QObject *parent = nullptr) 0288 : QObject(parent) 0289 { 0290 qputenv("ZANSHIN_UNIT_TEST_RUN", "1"); 0291 } 0292 0293 private slots: 0294 void shouldHaveApplicationModelAndSetErrorHandler() 0295 { 0296 // GIVEN 0297 Widgets::ApplicationComponents components; 0298 auto model = QObjectPtr::create(); 0299 0300 // WHEN 0301 components.setModel(model); 0302 0303 // THEN 0304 QCOMPARE(components.model(), model); 0305 auto errorHandlerBase = model->property("errorHandler").value<Presentation::ErrorHandler*>(); 0306 QVERIFY(errorHandlerBase); 0307 auto errorHandler = static_cast<Widgets::PageViewErrorHandler*>(errorHandlerBase); 0308 QVERIFY(errorHandler); 0309 QVERIFY(!errorHandler->pageView()); 0310 0311 // WHEN 0312 auto pageView = components.pageView(); 0313 0314 // THEN 0315 QCOMPARE(errorHandler->pageView(), pageView); 0316 } 0317 0318 void shouldApplyAvailableSourcesModelToAvailableSourcesView() 0319 { 0320 // GIVEN 0321 Widgets::ApplicationComponents components; 0322 auto model = QObjectPtr::create(); 0323 QObject availableSources; 0324 model->setProperty("availableSources", QVariant::fromValue(&availableSources)); 0325 0326 // WHEN 0327 components.setModel(model); 0328 0329 // THEN 0330 QCOMPARE(components.availableSourcesView()->model(), &availableSources); 0331 } 0332 0333 void shouldApplyAvailableSourcesModelAlsoToCreatedAvailableSourcesView() 0334 { 0335 // GIVEN 0336 Widgets::ApplicationComponents components; 0337 // Force creation 0338 components.availableSourcesView(); 0339 0340 auto model = QObjectPtr::create(); 0341 QObject availableSources; 0342 model->setProperty("availableSources", QVariant::fromValue(&availableSources)); 0343 0344 // WHEN 0345 components.setModel(model); 0346 0347 // THEN 0348 QCOMPARE(components.availableSourcesView()->model(), &availableSources); 0349 } 0350 0351 void shouldApplyAvailablePagesModelToAvailablePagesView() 0352 { 0353 // GIVEN 0354 Widgets::ApplicationComponents components; 0355 auto model = QObjectPtr::create(); 0356 0357 QObject availablePages; 0358 model->setProperty("availablePages", QVariant::fromValue(&availablePages)); 0359 0360 QObject availableSources; 0361 QAbstractItemModel *sourcesModel = new QStandardItemModel(model.data()); 0362 availableSources.setProperty("sourceListModel", QVariant::fromValue(sourcesModel)); 0363 model->setProperty("availableSources", QVariant::fromValue(&availableSources)); 0364 0365 // WHEN 0366 components.setModel(model); 0367 0368 // THEN 0369 QCOMPARE(components.availablePagesView()->model(), &availablePages); 0370 QCOMPARE(components.availablePagesView()->projectSourcesModel(), sourcesModel); 0371 } 0372 0373 void shouldApplyAvailablePagesModelAlsoToCreatedAvailablePagesView() 0374 { 0375 // GIVEN 0376 Widgets::ApplicationComponents components; 0377 // Force creation 0378 components.availablePagesView(); 0379 0380 auto model = QObjectPtr::create(); 0381 QObject availablePages; 0382 QAbstractItemModel *sourcesModel = new QStandardItemModel(model.data()); 0383 model->setProperty("dataSourcesModel", QVariant::fromValue(sourcesModel)); 0384 model->setProperty("availablePages", QVariant::fromValue(&availablePages)); 0385 0386 // WHEN 0387 components.setModel(model); 0388 0389 // THEN 0390 QCOMPARE(components.availablePagesView()->model(), &availablePages); 0391 QCOMPARE(components.availablePagesView()->projectSourcesModel(), sourcesModel); 0392 } 0393 0394 void shouldApplyCurrentPageModelToPageView() 0395 { 0396 // GIVEN 0397 Widgets::ApplicationComponents components; 0398 auto model = QObjectPtr::create(); 0399 QObject currentPage; 0400 model->setProperty("currentPage", QVariant::fromValue(¤tPage)); 0401 0402 // WHEN 0403 components.setModel(model); 0404 0405 // THEN 0406 QCOMPARE(components.pageView()->model(), ¤tPage); 0407 } 0408 0409 void shouldApplyCurrentPageModelAlsoToCreatedPageView() 0410 { 0411 // GIVEN 0412 Widgets::ApplicationComponents components; 0413 // Force creation 0414 components.pageView(); 0415 0416 auto model = QObjectPtr::create(); 0417 QObject currentPage; 0418 model->setProperty("currentPage", QVariant::fromValue(¤tPage)); 0419 0420 // WHEN 0421 components.setModel(model); 0422 0423 // THEN 0424 QCOMPARE(components.pageView()->model(), ¤tPage); 0425 } 0426 0427 void shouldApplyRunningTaskModelToPageView() 0428 { 0429 // GIVEN 0430 Widgets::ApplicationComponents components; 0431 auto model = QObjectPtr::create(); 0432 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0433 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0434 0435 // WHEN 0436 components.setModel(model); 0437 0438 // THEN 0439 QCOMPARE(components.pageView()->runningTaskModel(), runningTaskModel); 0440 } 0441 0442 void shouldApplyRunningTaskModelAlsoToCreatedPageView() 0443 { 0444 // GIVEN 0445 Widgets::ApplicationComponents components; 0446 // Force creation 0447 components.pageView(); 0448 0449 auto model = QObjectPtr::create(); 0450 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0451 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0452 0453 // WHEN 0454 components.setModel(model); 0455 0456 // THEN 0457 QCOMPARE(components.pageView()->runningTaskModel(), runningTaskModel); 0458 } 0459 0460 void shouldApplyEditorModelToEditorView() 0461 { 0462 // GIVEN 0463 Widgets::ApplicationComponents components; 0464 auto model = QObjectPtr::create(); 0465 QObject *editorModel = new EditorModelStub(model.data()); 0466 model->setProperty("editor", QVariant::fromValue(editorModel)); 0467 0468 // WHEN 0469 components.setModel(model); 0470 0471 // THEN 0472 QCOMPARE(components.editorView()->model(), editorModel); 0473 } 0474 0475 void shouldApplyEditorModelAlsoToCreatedPageView() 0476 { 0477 // GIVEN 0478 Widgets::ApplicationComponents components; 0479 // Force creation 0480 components.editorView(); 0481 0482 auto model = QObjectPtr::create(); 0483 QObject *editorModel = new EditorModelStub(model.data()); 0484 model->setProperty("editor", QVariant::fromValue(editorModel)); 0485 0486 // WHEN 0487 components.setModel(model); 0488 0489 // THEN 0490 QCOMPARE(components.editorView()->model(), editorModel); 0491 } 0492 0493 void shouldApplyRunningTaskModelToRunningTaskView() 0494 { 0495 // GIVEN 0496 Widgets::ApplicationComponents components; 0497 auto model = QObjectPtr::create(); 0498 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0499 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0500 0501 // WHEN 0502 components.setModel(model); 0503 0504 // THEN 0505 QCOMPARE(components.runningTaskView()->model(), runningTaskModel); 0506 } 0507 0508 void shouldApplyRunningTaskModelAlsoToCreatedRunningTaskView() 0509 { 0510 // GIVEN 0511 Widgets::ApplicationComponents components; 0512 // Force creation 0513 components.runningTaskView(); 0514 0515 auto model = QObjectPtr::create(); 0516 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0517 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0518 0519 // WHEN 0520 components.setModel(model); 0521 0522 // THEN 0523 QCOMPARE(components.runningTaskView()->model(), runningTaskModel); 0524 } 0525 0526 0527 void shouldPropageNullModelsToViews() 0528 { 0529 // GIVEN 0530 Widgets::ApplicationComponents components; 0531 0532 auto model = QObjectPtr::create(); 0533 auto availableSources = new QObject(model.data()); 0534 model->setProperty("availableSources", QVariant::fromValue(availableSources)); 0535 auto availablePages = new QObject(model.data()); 0536 model->setProperty("availablePages", QVariant::fromValue(availablePages)); 0537 auto currentPage = new QObject(model.data()); 0538 model->setProperty("currentPage", QVariant::fromValue(currentPage)); 0539 auto editorModel = new EditorModelStub(model.data()); 0540 model->setProperty("editor", QVariant::fromValue<QObject*>(editorModel)); 0541 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0542 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0543 0544 components.setModel(model); 0545 0546 // WHEN 0547 components.setModel(QObjectPtr()); 0548 components.availableSourcesView(); 0549 components.availablePagesView(); 0550 components.pageView(); 0551 components.editorView(); 0552 components.runningTaskView(); 0553 0554 // THEN 0555 QVERIFY(!components.availableSourcesView()->model()); 0556 QVERIFY(!components.availablePagesView()->model()); 0557 QVERIFY(!components.pageView()->model()); 0558 QVERIFY(!components.editorView()->model()); 0559 QVERIFY(!components.runningTaskView()->model()); 0560 } 0561 0562 void shouldPropageNullModelsToCreatedViews() 0563 { 0564 // GIVEN 0565 Widgets::ApplicationComponents components; 0566 components.availableSourcesView(); 0567 components.availablePagesView(); 0568 components.pageView(); 0569 components.editorView(); 0570 components.runningTaskView(); 0571 0572 auto model = QObjectPtr::create(); 0573 auto availableSources = new QObject(model.data()); 0574 model->setProperty("availableSources", QVariant::fromValue(availableSources)); 0575 auto availablePages = new QObject(model.data()); 0576 model->setProperty("availablePages", QVariant::fromValue(availablePages)); 0577 auto currentPage = new QObject(model.data()); 0578 model->setProperty("currentPage", QVariant::fromValue(currentPage)); 0579 auto editorModel = new EditorModelStub(model.data()); 0580 model->setProperty("editor", QVariant::fromValue<QObject*>(editorModel)); 0581 auto runningTaskModel = new RunningTaskModelStub(model.data()); 0582 model->setProperty("runningTaskModel", QVariant::fromValue<Presentation::RunningTaskModelInterface*>(runningTaskModel)); 0583 0584 components.setModel(model); 0585 0586 // WHEN 0587 components.setModel(QObjectPtr()); 0588 0589 // THEN 0590 QVERIFY(!components.availableSourcesView()->model()); 0591 QVERIFY(!components.availablePagesView()->model()); 0592 QVERIFY(!components.pageView()->model()); 0593 QVERIFY(!components.editorView()->model()); 0594 QVERIFY(!components.runningTaskView()->model()); 0595 } 0596 0597 void shouldApplyAvailablePagesSelectionToApplicationModel() 0598 { 0599 // GIVEN 0600 auto model = ApplicationModelStub::Ptr::create(); 0601 0602 AvailablePagesModelStub availablePagesModel; 0603 model->setProperty("availablePages", QVariant::fromValue<QObject*>(&availablePagesModel)); 0604 model->setProperty("currentPage", QVariant::fromValue<QObject*>(nullptr)); 0605 0606 QObject editorModel; 0607 editorModel.setProperty("task", 0608 QVariant::fromValue(Domain::Task::Ptr::create())); 0609 model->setProperty("editor", QVariant::fromValue<QObject*>(&editorModel)); 0610 0611 Widgets::ApplicationComponents components; 0612 components.setModel(model); 0613 0614 Widgets::AvailablePagesView *availablePagesView = components.availablePagesView(); 0615 auto pagesView = availablePagesView->findChild<QTreeView*>(QStringLiteral("pagesView")); 0616 QVERIFY(pagesView); 0617 0618 Widgets::PageView *pageView = components.pageView(); 0619 QVERIFY(pageView); 0620 QVERIFY(!pageView->model()); 0621 0622 QModelIndex index = pagesView->model()->index(0, 0); 0623 0624 // WHEN 0625 pagesView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); 0626 0627 // THEN 0628 QCOMPARE(availablePagesModel.createdPages.size(), 1); 0629 QCOMPARE(model->property("currentPage").value<QObject*>(), 0630 availablePagesModel.createdPages.first()); 0631 QCOMPARE(pageView->model(), 0632 availablePagesModel.createdPages.first()); 0633 QVERIFY(editorModel.property("task").value<Domain::Task::Ptr>().isNull()); 0634 } 0635 0636 void shouldApplyPageViewSelectionToEditorModel() 0637 { 0638 // GIVEN 0639 auto model = QObjectPtr::create(); 0640 0641 PageModelStub pageModel; 0642 pageModel.addTask(QStringLiteral("0. First task")); 0643 pageModel.addTask(QStringLiteral("1. Second task")); 0644 pageModel.addTask(QStringLiteral("2. Third task")); 0645 pageModel.addTask(QStringLiteral("3. Yet another task")); 0646 model->setProperty("currentPage", QVariant::fromValue<QObject*>(&pageModel)); 0647 0648 EditorModelStub editorModel; 0649 model->setProperty("editor", QVariant::fromValue<QObject*>(&editorModel)); 0650 0651 Widgets::ApplicationComponents components; 0652 components.setModel(model); 0653 0654 Widgets::PageView *pageView = components.pageView(); 0655 auto centralView = pageView->findChild<QTreeView*>(QStringLiteral("centralView")); 0656 QModelIndex index = centralView->model()->index(2, 0); 0657 0658 // WHEN 0659 centralView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect); 0660 0661 // THEN 0662 QCOMPARE(editorModel.property("task").value<Domain::Task::Ptr>(), 0663 pageModel.itemAtRow(index.row())); 0664 } 0665 0666 void shouldHaveDefaultActionsList() 0667 { 0668 // GIVEN 0669 Widgets::ApplicationComponents components; 0670 0671 // WHEN 0672 auto actions = components.globalActions(); 0673 0674 // THEN 0675 0676 // availablePages view 0677 auto available = components.availablePagesView(); 0678 auto availableGlobalActions = available->globalActions(); 0679 for (auto it = availableGlobalActions.cbegin(); it != availableGlobalActions.cend(); ++it) 0680 QCOMPARE(actions.value(it.key()), it.value()); 0681 0682 // availableSources view 0683 auto availableSources = components.availableSourcesView(); 0684 auto availableSourcesGlobalActions = availableSources->globalActions(); 0685 for (auto it = availableSourcesGlobalActions.cbegin(); it != availableSourcesGlobalActions.cend(); ++it) 0686 QCOMPARE(actions.value(it.key()), it.value()); 0687 0688 // page view 0689 auto page = components.pageView(); 0690 auto pageGlobalActions = page->globalActions(); 0691 for (auto it = pageGlobalActions.cbegin(); it != pageGlobalActions.cend(); ++it) 0692 QCOMPARE(actions.value(it.key()), it.value()); 0693 0694 // application component own action 0695 auto moveAction = components.findChild<QAction*>(QStringLiteral("moveItemAction")); 0696 QCOMPARE(actions.value(QStringLiteral("page_view_move")), moveAction); 0697 } 0698 0699 void shouldMoveItem() 0700 { 0701 // GIVEN 0702 auto model = QObjectPtr::create(); 0703 0704 PageModelStub pageModel; 0705 pageModel.addTask(QStringLiteral("0. First task")); 0706 pageModel.addTask(QStringLiteral("1. Second task")); 0707 pageModel.addTask(QStringLiteral("2. Third task")); 0708 pageModel.addTask(QStringLiteral("3. Yet another task")); 0709 model->setProperty("currentPage", QVariant::fromValue<QObject*>(&pageModel)); 0710 0711 AvailablePagesModelStub availablePagesModelStub; 0712 model->setProperty("availablePages", QVariant::fromValue<QObject*>(&availablePagesModelStub)); 0713 0714 QWidget *mainWidget = new QWidget; 0715 Widgets::ApplicationComponents components(mainWidget); 0716 components.setModel(model); 0717 0718 auto availablePageView = components.availablePagesView(); 0719 auto availablePagesTreeView = availablePageView->findChild<QTreeView*>(QStringLiteral("pagesView")); 0720 Q_ASSERT(availablePagesTreeView); 0721 0722 auto dialogStub = QuickSelectDialogStub::Ptr::create(); 0723 dialogStub->index = availablePagesModelStub.pageListModel()->index(0, 0); // inbox selected 0724 components.setQuickSelectDialogFactory([dialogStub] (QWidget *parent) { 0725 dialogStub->parent = parent; 0726 return dialogStub; 0727 }); 0728 0729 auto pageView = components.pageView(); 0730 auto centralView = pageView->findChild<QTreeView*>(QStringLiteral("centralView")); 0731 QModelIndex index1 = pageModel.itemModel.index(0,0); 0732 QModelIndex index2 = pageModel.itemModel.index(2,0); 0733 0734 auto filterWidget = pageView->findChild<Widgets::FilterWidget*>(QStringLiteral("filterWidget")); 0735 auto displayedModel = filterWidget->proxyModel(); 0736 auto displayedIndex = displayedModel->index(0, 0); 0737 auto displayedIndex2 = displayedModel->index(2, 0); 0738 0739 auto moveAction = components.findChild<QAction*>(QStringLiteral("moveItemAction")); 0740 0741 // WHEN 0742 pageModel.selectedItems << index1 << index2; 0743 centralView->selectionModel()->setCurrentIndex(displayedIndex, QItemSelectionModel::ClearAndSelect); 0744 centralView->selectionModel()->setCurrentIndex(displayedIndex2, QItemSelectionModel::Select); 0745 0746 moveAction->trigger(); 0747 0748 // THEN 0749 QCOMPARE(dialogStub->execCount, 1); 0750 QCOMPARE(dialogStub->parent, pageView); 0751 QCOMPARE(dialogStub->itemModel, availablePagesModelStub.pageListModel()); 0752 0753 QCOMPARE(availablePagesModelStub.itemModel.dropDestination, QStringLiteral("Inbox")); 0754 QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.size(), 2); 0755 QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.at(0), index1.data().toString()); 0756 QCOMPARE(availablePagesModelStub.itemModel.droppedItemDataString.at(1), index2.data().toString()); 0757 } 0758 }; 0759 0760 ZANSHIN_TEST_MAIN(ApplicationComponentsTest) 0761 0762 #include "applicationcomponentstest.moc"