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

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 "utils/dependencymanager.h"
0010 #include "utils/jobhandler.h"
0011 #include "utils/mockobject.h"
0012 
0013 #include "presentation/applicationmodel.h"
0014 #include "presentation/availablepagesmodel.h"
0015 #include "presentation/availablesourcesmodel.h"
0016 #include "presentation/editormodel.h"
0017 #include "presentation/pagemodel.h"
0018 #include "presentation/errorhandler.h"
0019 #include "presentation/runningtaskmodel.h"
0020 
0021 #include "testlib/fakejob.h"
0022 
0023 using namespace mockitopp;
0024 using namespace mockitopp::matcher;
0025 
0026 class FakeErrorHandler : public Presentation::ErrorHandler
0027 {
0028 public:
0029     void doDisplayMessage(const QString &message) override
0030     {
0031         m_message = message;
0032     }
0033 
0034     QString m_message;
0035 };
0036 
0037 class FakePageModel : public Presentation::PageModel
0038 {
0039     Q_OBJECT
0040 public:
0041     explicit FakePageModel(QObject *parent = nullptr)
0042         : Presentation::PageModel(parent) {}
0043 
0044     Domain::Task::Ptr addItem(const QString &, const QModelIndex &) override { return {}; }
0045     void removeItem(const QModelIndex &) override {}
0046     void promoteItem(const QModelIndex &) override {}
0047 
0048 private:
0049     QAbstractItemModel *createCentralListModel() override { return {}; }
0050 };
0051 
0052 class ApplicationModelTest : public QObject
0053 {
0054     Q_OBJECT
0055 public:
0056     explicit ApplicationModelTest(QObject *parent = nullptr)
0057         : QObject(parent)
0058     {
0059         Utils::DependencyManager::globalInstance().add<Presentation::AvailablePagesModel>(
0060             [] (Utils::DependencyManager *) {
0061                 return new Presentation::AvailablePagesModel(Domain::DataSourceQueries::Ptr(),
0062                                                              Domain::ProjectQueries::Ptr(),
0063                                                              Domain::ProjectRepository::Ptr(),
0064                                                              Domain::ContextQueries::Ptr(),
0065                                                              Domain::ContextRepository::Ptr(),
0066                                                              Domain::TaskQueries::Ptr(),
0067                                                              Domain::TaskRepository::Ptr());
0068         });
0069         Utils::DependencyManager::globalInstance().add<Presentation::EditorModel>(
0070             [] (Utils::DependencyManager *) {
0071                 return new Presentation::EditorModel;
0072         });
0073         Utils::DependencyManager::globalInstance().add<Presentation::AvailableSourcesModel>(
0074             [] (Utils::DependencyManager *) {
0075                 return new Presentation::AvailableSourcesModel(Domain::DataSourceQueries::Ptr(),
0076                                                                Domain::DataSourceRepository::Ptr());
0077         });
0078         Utils::DependencyManager::globalInstance().add<Presentation::RunningTaskModel>(
0079             [] (Utils::DependencyManager *) {
0080                 return new Presentation::RunningTaskModel(Domain::TaskQueries::Ptr(),
0081                                                          Domain::TaskRepository::Ptr());
0082         });
0083     }
0084 
0085 private slots:
0086     void shouldProvideAvailableSourcesModel()
0087     {
0088         // GIVEN
0089         Presentation::ApplicationModel app;
0090 
0091         // WHEN
0092         QObject *available = app.availableSources();
0093 
0094         // THEN
0095         QVERIFY(qobject_cast<Presentation::AvailableSourcesModel*>(available));
0096     }
0097 
0098     void shouldProvideAvailablePagesModel()
0099     {
0100         // GIVEN
0101         Presentation::ApplicationModel app;
0102 
0103         // WHEN
0104         QObject *available = app.availablePages();
0105 
0106         // THEN
0107         QVERIFY(qobject_cast<Presentation::AvailablePagesModel*>(available));
0108     }
0109 
0110     void shouldProvideCurrentPage()
0111     {
0112         // GIVEN
0113         Presentation::ApplicationModel app;
0114         QVERIFY(!app.currentPage());
0115         QSignalSpy spy(&app, &Presentation::ApplicationModel::currentPageChanged);
0116 
0117         // WHEN
0118         auto page = new FakePageModel(this);
0119         app.setCurrentPage(page);
0120 
0121         // THEN
0122         QCOMPARE(app.currentPage(), page);
0123         QCOMPARE(spy.count(), 1);
0124         QCOMPARE(spy.takeFirst().at(0).value<QObject*>(), page);
0125     }
0126 
0127     void shouldSupportNullPage()
0128     {
0129         // GIVEN
0130         Presentation::ApplicationModel app;
0131         auto page = new FakePageModel(this);
0132         app.setCurrentPage(page);
0133         QCOMPARE(app.currentPage(), page);
0134         QSignalSpy spy(&app, &Presentation::ApplicationModel::currentPageChanged);
0135 
0136         // WHEN
0137         app.setCurrentPage(nullptr);
0138 
0139         // THEN
0140         QVERIFY(!app.currentPage());
0141         QCOMPARE(spy.count(), 1);
0142         QVERIFY(!spy.takeFirst().at(0).value<QObject*>());
0143     }
0144 
0145     void shouldTakeOwnershipOfCurrentPage()
0146     {
0147         // GIVEN
0148         auto page = QPointer<QObject>(new FakePageModel(this));
0149 
0150         {
0151             Presentation::ApplicationModel app;
0152 
0153             // WHEN
0154             app.setCurrentPage(page.data());
0155 
0156             // THEN
0157             QVERIFY(!page->parent());
0158             QCOMPARE(app.currentPage(), page.data());
0159         }
0160         // We don't crash and page is deleted
0161         QVERIFY(!page);
0162     }
0163 
0164     void shouldProvideEditorModel()
0165     {
0166         // GIVEN
0167         Presentation::ApplicationModel app;
0168 
0169         // WHEN
0170         QObject *page = app.editor();
0171 
0172         // THEN
0173         QVERIFY(qobject_cast<Presentation::EditorModel*>(page));
0174     }
0175 
0176     void shouldProvideRunningTaskModel()
0177     {
0178         // GIVEN
0179         Presentation::ApplicationModel app;
0180 
0181         // WHEN
0182         QObject *model = app.runningTaskModel();
0183 
0184         // THEN
0185         QVERIFY(qobject_cast<Presentation::RunningTaskModel*>(model));
0186     }
0187 
0188     void shouldSetErrorHandlerToAllModels()
0189     {
0190         // GIVEN
0191 
0192         // An ErrorHandler
0193         FakeErrorHandler errorHandler;
0194         Presentation::ApplicationModel app;
0195         app.setCurrentPage(new FakePageModel);
0196 
0197         // WHEN
0198         app.setErrorHandler(&errorHandler);
0199 
0200         // THEN
0201         auto availableSource = static_cast<Presentation::AvailableSourcesModel*>(app.availableSources());
0202         auto availablePages = static_cast<Presentation::AvailablePagesModel*>(app.availablePages());
0203         auto editor = static_cast<Presentation::EditorModel*>(app.editor());
0204         auto page = static_cast<Presentation::PageModel*>(app.currentPage());
0205         auto runningTask = static_cast<Presentation::RunningTaskModel*>(app.runningTaskModel());
0206         QCOMPARE(availableSource->errorHandler(), &errorHandler);
0207         QCOMPARE(availablePages->errorHandler(), &errorHandler);
0208         QCOMPARE(editor->errorHandler(), &errorHandler);
0209         QCOMPARE(page->errorHandler(), &errorHandler);
0210         QCOMPARE(runningTask->errorHandler(), &errorHandler);
0211 
0212         // WHEN
0213         FakeErrorHandler errorHandler2;
0214 
0215         app.setErrorHandler(&errorHandler2);
0216 
0217         // THEN
0218         QCOMPARE(availableSource->errorHandler(), &errorHandler2);
0219         QCOMPARE(availablePages->errorHandler(), &errorHandler2);
0220         QCOMPARE(editor->errorHandler(), &errorHandler2);
0221         QCOMPARE(page->errorHandler(), &errorHandler2);
0222         QCOMPARE(runningTask->errorHandler(), &errorHandler2);
0223     }
0224 
0225     void shouldClearJobHandlersOnExit()
0226     {
0227         // GIVEN
0228         auto app = new Presentation::ApplicationModel;
0229         Utils::JobHandler::install(new FakeJob, [] { qFatal("Shouldn't happen"); });
0230         QCOMPARE(Utils::JobHandler::jobCount(), 1);
0231 
0232         // WHEN
0233         delete app;
0234 
0235         // THEN
0236         QCOMPARE(Utils::JobHandler::jobCount(), 0);
0237         QTest::qWait(FakeJob::DURATION * 2);
0238     }
0239 };
0240 
0241 ZANSHIN_TEST_MAIN(ApplicationModelTest)
0242 
0243 #include "applicationmodeltest.moc"