File indexing completed on 2024-05-12 05:38:08

0001 /*
0002     SPDX-FileCopyrightText: 2016 Eike Hein <hein@kde.org>
0003     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include <QObject>
0009 #include <QSignalSpy>
0010 #include <QTest>
0011 
0012 #include "launchertasksmodel.h"
0013 #include "tasktools.h"
0014 
0015 using namespace TaskManager;
0016 
0017 class LauncherTasksModelTest : public QObject
0018 {
0019     Q_OBJECT
0020 
0021 private Q_SLOTS:
0022     void initTestCase();
0023 
0024     void shouldRoundTripLauncherUrlList();
0025     void shouldIgnoreInvalidUrls();
0026     void shouldAcceptSpaces();
0027     void shouldRejectDuplicates();
0028     void shouldAddRemoveLauncher();
0029     void shouldReturnValidLauncherPositions();
0030     void shouldReturnValidData();
0031     void shouldNotCrashRemovingLauncherBug472378();
0032 
0033 private:
0034     QStringList m_urlStrings;
0035 };
0036 
0037 void LauncherTasksModelTest::initTestCase()
0038 {
0039     qApp->setProperty("org.kde.KActivities.core.disableAutostart", true);
0040     m_urlStrings = QStringList{QUrl::fromLocalFile(QFINDTESTDATA("data/applications/org.kde.dolphin.desktop")).toString(),
0041                                QUrl::fromLocalFile(QFINDTESTDATA("data/applications/org.kde.konversation.desktop")).toString()};
0042     // We don't want the globally installed apps to interfere and want the test to use our data files
0043     qputenv("XDG_DATA_DIRS", QFINDTESTDATA("data").toLocal8Bit());
0044 }
0045 
0046 void LauncherTasksModelTest::shouldRoundTripLauncherUrlList()
0047 {
0048     LauncherTasksModel m;
0049 
0050     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0051     QVERIFY(launcherListChangedSpy.isValid());
0052 
0053     m.setLauncherList(m_urlStrings);
0054 
0055     QCOMPARE(launcherListChangedSpy.count(), 1);
0056 
0057     QCOMPARE(m.launcherList(), m_urlStrings);
0058 
0059     QVERIFY(launcherUrlsMatch(m.data(m.index(0, 0), AbstractTasksModel::LauncherUrl).toUrl(), QUrl(m_urlStrings.at(0))));
0060     QVERIFY(launcherUrlsMatch(m.data(m.index(1, 0), AbstractTasksModel::LauncherUrl).toUrl(), QUrl(m_urlStrings.at(1))));
0061 }
0062 
0063 void LauncherTasksModelTest::shouldIgnoreInvalidUrls()
0064 {
0065     LauncherTasksModel m;
0066 
0067     QStringList urlStrings;
0068     urlStrings << QLatin1String("GARBAGE URL");
0069 
0070     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0071     QVERIFY(launcherListChangedSpy.isValid());
0072 
0073     m.setLauncherList(urlStrings);
0074 
0075     QCOMPARE(launcherListChangedSpy.count(), 0);
0076 
0077     bool added = m.requestAddLauncher(QUrl(urlStrings.at(0)));
0078 
0079     QVERIFY(!added);
0080     QCOMPARE(launcherListChangedSpy.count(), 0);
0081 
0082     QCOMPARE(m.launcherList(), QStringList());
0083 }
0084 
0085 void LauncherTasksModelTest::shouldAcceptSpaces()
0086 {
0087     LauncherTasksModel m;
0088 
0089     const QStringList urlStrings{QLatin1String("applications:App with spaces.desktop")};
0090 
0091     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0092     QVERIFY(launcherListChangedSpy.isValid());
0093 
0094     const bool added = m.requestAddLauncher(QUrl(urlStrings.at(0)));
0095 
0096     QVERIFY(added);
0097     QCOMPARE(launcherListChangedSpy.count(), 1);
0098 
0099     QCOMPARE(m.launcherList(), QStringList() << urlStrings.at(0));
0100 }
0101 
0102 void LauncherTasksModelTest::shouldRejectDuplicates()
0103 {
0104     LauncherTasksModel m;
0105 
0106     const QStringList urlStrings = {QUrl::fromLocalFile(QFINDTESTDATA("data/applications/org.kde.dolphin.desktop")).toString(),
0107                                     QUrl::fromLocalFile(QFINDTESTDATA("data/applications/org.kde.dolphin.desktop")).toString()};
0108 
0109     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0110     QVERIFY(launcherListChangedSpy.isValid());
0111 
0112     m.setLauncherList(urlStrings);
0113 
0114     QCOMPARE(launcherListChangedSpy.count(), 1);
0115 
0116     bool added = m.requestAddLauncher(QUrl(urlStrings.at(0)));
0117 
0118     QVERIFY(!added);
0119     QCOMPARE(launcherListChangedSpy.count(), 1);
0120 
0121     QCOMPARE(m.launcherList(), QStringList() << urlStrings.at(0));
0122 }
0123 
0124 void LauncherTasksModelTest::shouldAddRemoveLauncher()
0125 {
0126     LauncherTasksModel m;
0127 
0128     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0129     QVERIFY(launcherListChangedSpy.isValid());
0130 
0131     bool added = m.requestAddLauncher(QUrl(m_urlStrings.at(0)));
0132 
0133     QVERIFY(added);
0134     QCOMPARE(launcherListChangedSpy.count(), 1);
0135 
0136     QVERIFY(launcherUrlsMatch(QUrl(m.launcherList().at(0)), QUrl(m_urlStrings.at(0))));
0137 
0138     bool removed = m.requestRemoveLauncher(QUrl(m_urlStrings.at(0)));
0139 
0140     QVERIFY(removed);
0141     QCOMPARE(launcherListChangedSpy.count(), 2);
0142 
0143     removed = m.requestRemoveLauncher(QUrl(m_urlStrings.at(0)));
0144 
0145     QVERIFY(!removed);
0146 
0147     QCOMPARE(m.launcherList(), QStringList());
0148 }
0149 
0150 void LauncherTasksModelTest::shouldReturnValidLauncherPositions()
0151 {
0152     LauncherTasksModel m;
0153 
0154     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0155     QVERIFY(launcherListChangedSpy.isValid());
0156 
0157     m.setLauncherList(m_urlStrings);
0158 
0159     QCOMPARE(launcherListChangedSpy.count(), 1);
0160 
0161     QCOMPARE(m.launcherPosition(QUrl(m_urlStrings.at(0))), 0);
0162     QCOMPARE(m.launcherPosition(QUrl(m_urlStrings.at(1))), 1);
0163 }
0164 
0165 void LauncherTasksModelTest::shouldReturnValidData()
0166 {
0167     // FIXME Reuse TaskToolsTest app link setup, then run URLs through model.
0168 }
0169 
0170 void LauncherTasksModelTest::shouldNotCrashRemovingLauncherBug472378()
0171 {
0172     LauncherTasksModel m;
0173 
0174     QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
0175     QVERIFY(launcherListChangedSpy.isValid());
0176 
0177     // Add a launcher using an application url
0178     QUrl url(QStringLiteral("applications:GammaRay.desktop"));
0179     bool added = m.requestAddLauncher(url);
0180     QVERIFY(added);
0181     QCOMPARE(launcherListChangedSpy.count(), 1);
0182     QVERIFY(launcherUrlsMatch(QUrl(m.launcherList().at(0)), url));
0183 
0184     // Add a second launcher and ensure it is added to appDataCache
0185     added = m.requestAddLauncher(QUrl(m_urlStrings.at(0)));
0186     QVERIFY(added);
0187     QCOMPARE(launcherListChangedSpy.count(), 2);
0188     QVERIFY(launcherUrlsMatch(m.data(m.index(1, 0), AbstractTasksModel::LauncherUrl).toUrl(), QUrl(m_urlStrings.at(0))));
0189 
0190     // Remove a launcher, and ensure it doesn't share a reference with the original url
0191     // This hit a use after free, bug #472378
0192     url.detach();
0193     bool removed = m.requestRemoveLauncher(url);
0194     QVERIFY(removed);
0195     QCOMPARE(launcherListChangedSpy.count(), 3);
0196 }
0197 
0198 QTEST_MAIN(LauncherTasksModelTest)
0199 
0200 #include "launchertasksmodeltest.moc"