File indexing completed on 2024-12-22 05:15:17

0001 /*
0002     SPDX-FileCopyrightText: 2022 Arjen Hiemstra <ahiemstra@heimr.nl>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "../runnermatchesmodel.h"
0008 #include "../runnermodel.h"
0009 
0010 #include <memory>
0011 
0012 #include <QAbstractItemModelTester>
0013 #include <QSignalSpy>
0014 #include <QStandardPaths>
0015 #include <QTest>
0016 
0017 #include <KConfigGroup>
0018 #include <KSharedConfig>
0019 #include <KSycoca>
0020 
0021 static const QString s_keyword = QStringLiteral("audacity");
0022 
0023 class TestRunnerModel : public QObject
0024 {
0025     Q_OBJECT
0026 private Q_SLOTS:
0027     void initTestCase();
0028     void cleanupTestCase();
0029 
0030     void testQuery();
0031     void testMergeResults();
0032 };
0033 
0034 void TestRunnerModel::initTestCase()
0035 {
0036     QStandardPaths::setTestModeEnabled(true);
0037 
0038     QFileInfo desktopFile(QFINDTESTDATA("../../../../runners/services/autotests/fixtures/audacity.desktop"));
0039     QVERIFY(desktopFile.exists());
0040     const QString appsPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
0041     QDir(appsPath).removeRecursively();
0042     QVERIFY(QDir().mkpath(appsPath));
0043     QVERIFY(QFile::copy(desktopFile.absoluteFilePath(), appsPath + QDir::separator() + desktopFile.fileName()));
0044 
0045     QSignalSpy databaseChangedSpy(KSycoca::self(), &KSycoca::databaseChanged);
0046     KSycoca::self()->ensureCacheValid();
0047     databaseChangedSpy.wait(2500);
0048 
0049     // Disable all DBus runners, those might cause a slowdown/timeout on CI
0050     KConfigGroup pluginsConfig = KSharedConfig::openConfig(QStringLiteral("krunnerrc"))->group(QStringLiteral("Plugins"));
0051     const auto runners = KRunner::RunnerManager::runnerMetaDataList();
0052     for (const KPluginMetaData &runner : runners) {
0053         if (runner.value(QStringLiteral("X-Plasma-API")).startsWith(QLatin1String("DBus"))) {
0054             pluginsConfig.writeEntry(runner.pluginId() + QLatin1String("Enabled"), false);
0055         }
0056     }
0057 }
0058 
0059 void TestRunnerModel::cleanupTestCase()
0060 {
0061     const QString appsPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
0062     QDir(appsPath).removeRecursively();
0063     KSharedConfig::openConfig(QStringLiteral("krunnerrc"))->deleteGroup(QStringLiteral("Plugins"));
0064 }
0065 
0066 void TestRunnerModel::testQuery()
0067 {
0068     std::unique_ptr<RunnerModel> model = std::make_unique<RunnerModel>();
0069     model->setRunners(QStringList{QStringLiteral("krunner_services")});
0070     std::unique_ptr<QAbstractItemModelTester> modelTest(new QAbstractItemModelTester(model.get()));
0071     QSignalSpy countChangedSpy(model.get(), &RunnerModel::countChanged);
0072     QSignalSpy queryFinishedSpy(model.get(), &RunnerModel::queryFinished);
0073 
0074     // Searching for a really basic string should at least show some results.
0075     model->setQuery(s_keyword);
0076 
0077     queryFinishedSpy.wait();
0078     QVERIFY(model->count() > 0);
0079     QCOMPARE(countChangedSpy.count(), 1);
0080     QCOMPARE(model->count(), model->rowCount());
0081 
0082     for (int i = 0; i < model->count(); ++i) {
0083         auto rowModel = qobject_cast<RunnerMatchesModel *>(model->modelForRow(i));
0084         QVERIFY(rowModel != nullptr);
0085         QVERIFY(rowModel->rowCount() > 0);
0086     }
0087 
0088     // If we then change the query to something that shouldn't show anything,
0089     // the model should not change categories but matches should be gone.
0090     auto previousCount = model->count();
0091     model->setQuery(QStringLiteral("something_that_really_shouldn't_return_any_results"));
0092 
0093     queryFinishedSpy.wait();
0094 
0095     QCOMPARE(model->count(), previousCount);
0096     QCOMPARE(countChangedSpy.count(), 1);
0097 
0098     for (int i = 0; i < model->count(); ++i) {
0099         auto rowModel = qobject_cast<RunnerMatchesModel *>(model->modelForRow(i));
0100         QVERIFY(rowModel != nullptr);
0101         QCOMPARE(rowModel->rowCount(), 0);
0102     }
0103 }
0104 
0105 void TestRunnerModel::testMergeResults()
0106 {
0107     std::unique_ptr<RunnerModel> model = std::make_unique<RunnerModel>();
0108     model->setMergeResults(true);
0109     std::unique_ptr<QAbstractItemModelTester> modelTest(new QAbstractItemModelTester(model.get()));
0110     QSignalSpy queryFinished(model.get(), &RunnerModel::queryFinished);
0111 
0112     // A basic query should return some results.
0113     model->setQuery(s_keyword);
0114     QCOMPARE(model->count(), 1);
0115     qWarning() << model->modelForRow(0)->runnerManager()->runners();
0116     QVERIFY(queryFinished.wait());
0117 
0118     model->setQuery(QString{});
0119     QVERIFY(queryFinished.wait());
0120     QCOMPARE(model->modelForRow(0)->count(), 0);
0121 }
0122 
0123 QTEST_MAIN(TestRunnerModel)
0124 #include "testrunnermodel.moc"