Warning, file /frameworks/knewstuff/autotests/kmoretools/kmoretoolstest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002     SPDX-FileCopyrightText: 2014, 2015 Gregor Mi <codestruct@posteo.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include <../src/kmoretools/kmoretools.h>
0008 #include <../src/kmoretools/kmoretools_p.h>
0009 #include <../src/kmoretools/kmoretoolspresets.h>
0010 
0011 #include <QPushButton>
0012 #include <QRegularExpression>
0013 #include <QStandardPaths>
0014 #include <QTest>
0015 
0016 class KMoreToolsTest : public QObject
0017 {
0018     Q_OBJECT
0019 
0020 private Q_SLOTS:
0021     void initTestCase();
0022 
0023     // corner, error cases and impl details:
0024     void testDesktopFileWithNoExec();
0025     void testDesktopFileWithInvalidHeader();
0026     void testDesktopFileWithNoName();
0027     void testDesktopFileNotProvided();
0028     void testDetectByExecLineButNoFileProvided();
0029     void testRegisterServiceTwice();
0030     void testMenuBuilderWithConfigPostfix();
0031 
0032     // use cases:
0033     void testNotInstalledAppStructure();
0034     void testNotInstalledAppIcon();
0035     void testUniqueItemIdForOwnActions();
0036     void test_buildMenu_PruneDuplicateNotInstalledService();
0037     void test_KMoreToolsPresets_registerServicesByGrouping();
0038 
0039     // kmoretools_p.h tests:
0040     void testMenuItemIdGen();
0041     void test_MenuItemDto_removeMenuAmpersand();
0042     void test_MenuStructureDto_sortListBySection();
0043     void test_MenuStructureDto_serialize();
0044     void test_MenuStructureDto_deserialize();
0045     void test_KmtUrlUtil_localFileAbsoluteDir();
0046 };
0047 
0048 void KMoreToolsTest::initTestCase()
0049 {
0050     QStandardPaths::setTestModeEnabled(true);
0051 
0052     const QString dest = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kf5/kmoretools/unittest-kmoretools/1/");
0053     QVERIFY(QDir(dest).removeRecursively());
0054     QVERIFY(QDir().mkpath(dest));
0055     for (const QString &fileName : {QStringLiteral("a.desktop"), QStringLiteral("b.desktop"), QStringLiteral("c.desktop")}) {
0056         const QString srcFile = QFINDTESTDATA("1/" + fileName + ".notranslate");
0057         QVERIFY(!srcFile.isEmpty());
0058         QVERIFY(QFile::copy(srcFile, dest + fileName));
0059     }
0060 
0061     const QString dest2 = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/kf5/kmoretools/unittest-kmoretools/2/");
0062     QVERIFY(QDir(dest2).removeRecursively());
0063     QVERIFY(QDir().mkpath(dest2));
0064     const auto fileNames = {QStringLiteral("org.kde.kate.desktop"),
0065                             QStringLiteral("org.kde.kate.png"),
0066                             QStringLiteral("mynotinstalledapp.desktop"),
0067                             QStringLiteral("mynotinstalledapp.png"),
0068                             QStringLiteral("mynotinstapp2.desktop")};
0069     for (const QString &fileName : fileNames) {
0070         const QString origFile = fileName.endsWith(QLatin1String("desktop")) ? fileName + _(".notranslate") : fileName;
0071         const QString srcFile = QFINDTESTDATA("2/" + origFile);
0072         QVERIFY(!srcFile.isEmpty());
0073         QVERIFY(QFile::copy(srcFile, dest2 + fileName));
0074     }
0075 }
0076 
0077 /**
0078  * no Exec line => not a usable desktop file
0079  */
0080 void KMoreToolsTest::testDesktopFileWithNoExec()
0081 {
0082     KMoreTools kmt(_("unittest-kmoretools/1"));
0083     auto aApp = kmt.registerServiceByDesktopEntryName(_("a"));
0084     QVERIFY(!aApp);
0085 }
0086 
0087 /**
0088  * invalid header? => Exec line not found
0089  */
0090 void KMoreToolsTest::testDesktopFileWithInvalidHeader()
0091 {
0092     KMoreTools kmt(_("unittest-kmoretools/1"));
0093     auto bApp = kmt.registerServiceByDesktopEntryName(_("b"));
0094     QVERIFY(!bApp);
0095 }
0096 
0097 /**
0098  * no Name line => name() will be filled automatically, everything will be ok
0099  */
0100 void KMoreToolsTest::testDesktopFileWithNoName()
0101 {
0102     KMoreTools kmt(_("unittest-kmoretools/1"));
0103     auto cApp = kmt.registerServiceByDesktopEntryName(_("c"));
0104     QVERIFY(cApp);
0105     QCOMPARE(cApp->desktopEntryName(), _("c"));
0106     QVERIFY(cApp->kmtProvidedService());
0107     QCOMPARE(cApp->kmtProvidedService()->exec(), _("hallo"));
0108 }
0109 
0110 /**
0111  * desktop file not present => warning
0112  */
0113 void KMoreToolsTest::testDesktopFileNotProvided()
0114 {
0115     KMoreTools kmt(_("unittest-kmoretools/1"));
0116     auto eeeApp = kmt.registerServiceByDesktopEntryName(_("eee"));
0117     QVERIFY(eeeApp);
0118     QCOMPARE(eeeApp->desktopEntryName(), _("eee"));
0119 }
0120 
0121 void KMoreToolsTest::testDetectByExecLineButNoFileProvided()
0122 {
0123     KMoreTools kmt(_("unittest-kmoretools/1"));
0124     auto eeeApp = kmt.registerServiceByDesktopEntryName(_("eee"), QString(), KMoreTools::ServiceLocatingMode_ByProvidedExecLine);
0125     QVERIFY(!eeeApp);
0126 }
0127 
0128 void KMoreToolsTest::testRegisterServiceTwice()
0129 {
0130     KMoreTools kmt(_("unittest-kmoretools/1"));
0131     /*auto eeeApp1 = */ kmt.registerServiceByDesktopEntryName(_("eee"));
0132     /*auto eeeApp2 = */ kmt.registerServiceByDesktopEntryName(_("eee"));
0133     // todo: verify that there is only the last item in the internal service list
0134 }
0135 
0136 void KMoreToolsTest::testMenuBuilderWithConfigPostfix()
0137 {
0138     KMoreTools kmt(_("unittest-kmoretools/1"));
0139     auto menuBuilder1 = kmt.menuBuilder();
0140     auto menuBuilder2 = kmt.menuBuilder();
0141     auto menuBuilder3 = kmt.menuBuilder(_("postfix"));
0142     auto menuBuilder4 = kmt.menuBuilder(_("postfix"));
0143 
0144     QVERIFY(menuBuilder1 == menuBuilder2);
0145     QVERIFY(menuBuilder3 != menuBuilder1);
0146     QVERIFY(menuBuilder3 == menuBuilder4);
0147 }
0148 
0149 void KMoreToolsTest::testNotInstalledAppStructure()
0150 {
0151     KMoreTools kmt(_("unittest-kmoretools/2"));
0152     const auto mynotInstalledApp = kmt.registerServiceByDesktopEntryName(_("mynotinstalledapp"));
0153     const auto menuBuilder = kmt.menuBuilder();
0154     menuBuilder->addMenuItem(mynotInstalledApp);
0155     QString s = menuBuilder->menuStructureAsString(false);
0156     qDebug() << s;
0157     QCOMPARE(s, _("|main|:|more|:|notinstalled|:mynotinstalledapp."));
0158 }
0159 
0160 void KMoreToolsTest::testNotInstalledAppIcon()
0161 {
0162     KMoreTools kmt(_("unittest-kmoretools/2"));
0163     const auto mynotInstalledApp = kmt.registerServiceByDesktopEntryName(_("mynotinstalledapp"));
0164     QVERIFY(!mynotInstalledApp->icon().isNull());
0165 }
0166 
0167 void KMoreToolsTest::testUniqueItemIdForOwnActions()
0168 {
0169     KMoreTools kmt(_("unittest-kmoretools/1"));
0170     auto menuBuilder = kmt.menuBuilder();
0171     QAction a1(_("a"), nullptr);
0172     auto item1 = menuBuilder->addMenuItem(&a1, _("aaa"));
0173     QAction a2(_("b"), nullptr);
0174     auto item2 = menuBuilder->addMenuItem(&a2, _("aaa")); // same id to see if it will be made unique
0175 
0176     QCOMPARE(item1->id(), _("aaa0"));
0177     QCOMPARE(item2->id(), _("aaa1"));
0178 }
0179 
0180 bool menuAtLeastOneActionWithText(const QMenu *menu, const QString &text)
0181 {
0182     const auto lstActions = menu->actions();
0183     for (auto a : lstActions) {
0184         if (a->text() == text) {
0185             return true;
0186         }
0187     }
0188 
0189     return false;
0190 }
0191 
0192 bool menuAtLeastNoActionWithText(const QMenu *menu, const QString &text)
0193 {
0194     const auto lstActions = menu->actions();
0195     for (auto a : lstActions) {
0196         if (a->text() == text) {
0197             qDebug() << a->text();
0198             return false;
0199         }
0200     }
0201 
0202     return true;
0203 }
0204 
0205 void KMoreToolsTest::test_buildMenu_PruneDuplicateNotInstalledService()
0206 {
0207     KMoreTools kmt(_("unittest-kmoretools/2"));
0208     const auto mynotInstalledApp = kmt.registerServiceByDesktopEntryName(_("mynotinstalledapp"));
0209     const auto menuBuilder = kmt.menuBuilder();
0210     menuBuilder->addMenuItem(mynotInstalledApp);
0211     menuBuilder->addMenuItem(mynotInstalledApp); // duplicate (which can make sense if the service will be called with different arguments)
0212     QMenu menu;
0213     menuBuilder->buildByAppendingToMenu(&menu);
0214     QCOMPARE(menu.actions().count(), 4); // "Not installed section", "Not installed app" (only once), "Separator", "Configure menu..."
0215 }
0216 
0217 void KMoreToolsTest::test_KMoreToolsPresets_registerServicesByGrouping()
0218 {
0219     KMoreTools kmt(_("unittest-kmoretools/3"));
0220     auto list = KMoreToolsPresets::registerServicesByGroupingNames(&kmt, {_("screenshot-take")});
0221 
0222     if (std::find_if(list.begin(),
0223                      list.end(),
0224                      [](KMoreToolsService *s) {
0225                          return s->desktopEntryName() == _("org.kde.spectacle");
0226                      })
0227         != list.end()) {
0228         QVERIFY(true); // at least spectacle should currently be present
0229     } else {
0230         QVERIFY(false);
0231     }
0232 }
0233 
0234 void KMoreToolsTest::testMenuItemIdGen()
0235 {
0236     KmtMenuItemIdGen idGen;
0237     QCOMPARE(idGen.getId(_("a")), _("a0"));
0238     QCOMPARE(idGen.getId(_("a")), _("a1"));
0239     QCOMPARE(idGen.getId(_("b")), _("b0"));
0240     QCOMPARE(idGen.getId(_("a")), _("a2"));
0241 }
0242 
0243 QDebug operator<<(QDebug d, const KmtMenuItemDto &m)
0244 {
0245     d << "id:" << m.id << ", section:" << m.menuSection << ", isInstalled:" << m.isInstalled;
0246     return d;
0247 }
0248 
0249 void KMoreToolsTest::test_MenuItemDto_removeMenuAmpersand()
0250 {
0251     QCOMPARE(KmtMenuItemDto::removeMenuAmpersand(_("&Hallo")), _("Hallo"));
0252     QCOMPARE(KmtMenuItemDto::removeMenuAmpersand(_("Hall&o")), _("Hallo"));
0253     QCOMPARE(KmtMenuItemDto::removeMenuAmpersand(_("H&all&o")), _("Hallo")); // is this ok for menus items?
0254     QCOMPARE(KmtMenuItemDto::removeMenuAmpersand(_("&&Hallo")), _("&Hallo"));
0255     QCOMPARE(KmtMenuItemDto::removeMenuAmpersand(_("&Hall&&o")), _("Hall&o"));
0256 }
0257 
0258 // Support method for KMoreToolsTest::test_MenuStructureDto_sortListBySection,
0259 // generates a list of menu items ordered by the passed-in indexes; this
0260 // helps test multiple permutations of the same list. Don't try *all*
0261 // permutations, since it's a stable sort -- items inside a section
0262 // must remain in the same relative order.
0263 //
0264 static void sortListBySection(int indexes[5])
0265 {
0266     KmtMenuStructureDto mstruct;
0267 
0268     KmtMenuItemDto ma1;
0269     ma1.id = QStringLiteral("main1");
0270     ma1.menuSection = KMoreTools::MenuSection_Main;
0271 
0272     KmtMenuItemDto mo1;
0273     mo1.id = QStringLiteral("more1");
0274     mo1.menuSection = KMoreTools::MenuSection_More;
0275 
0276     KmtMenuItemDto ma3;
0277     ma3.id = QStringLiteral("main3_ni");
0278     ma3.menuSection = KMoreTools::MenuSection_Main;
0279     ma3.isInstalled = false; // !!!
0280 
0281     KmtMenuItemDto mo2;
0282     mo2.id = QStringLiteral("more2");
0283     mo2.menuSection = KMoreTools::MenuSection_More;
0284 
0285     KmtMenuItemDto ma2;
0286     ma2.id = QStringLiteral("main2");
0287     ma2.menuSection = KMoreTools::MenuSection_Main;
0288 
0289     KmtMenuItemDto *items[5] = {&ma1, &mo1, &ma3, &mo2, &ma2};
0290 
0291     mstruct.list.clear();
0292     for (unsigned int i = 0; i < 5; ++i) {
0293         mstruct.list.append(*items[indexes[i]]);
0294     }
0295     mstruct.stableSortListBySection();
0296 
0297     QCOMPARE(mstruct.list[0].id, _("main1")); // 1. main
0298     QCOMPARE(mstruct.list[1].id, _("main2"));
0299     QCOMPARE(mstruct.list[2].id, _("more1")); // 2. more
0300     QCOMPARE(mstruct.list[3].id, _("more2"));
0301     QCOMPARE(mstruct.list[4].id, _("main3_ni")); // 3. not installed
0302 }
0303 
0304 void KMoreToolsTest::test_MenuStructureDto_sortListBySection()
0305 {
0306     int indexes_plain[5] = {0, 1, 2, 3, 4}; // In normal order
0307     int indexes_presorted[5] = {0, 4, 1, 3, 2};
0308     int indexes_interleave[5] = {0, 1, 3, 4, 2};
0309     int indexes_morefirst[5] = {1, 3, 0, 4, 2};
0310     int indexes_uninstalledfirst[5] = {2, 1, 0, 4, 3};
0311     // Permutations of where the uninstalled item is inserted
0312     int indexes_uninstalled_p0[5] = {2, 0, 1, 3, 4};
0313     int indexes_uninstalled_p1[5] = {0, 2, 1, 3, 4};
0314     int indexes_uninstalled_p2[5] = {0, 1, 2, 3, 4};
0315     int indexes_uninstalled_p3[5] = {0, 1, 3, 2, 4};
0316     int indexes_uninstalled_p4[5] = {0, 1, 3, 4, 2};
0317 
0318     qDebug() << "Plain";
0319     sortListBySection(indexes_plain);
0320     qDebug() << "Presorted";
0321     sortListBySection(indexes_presorted);
0322     qDebug() << "Interleaved";
0323     sortListBySection(indexes_interleave);
0324     qDebug() << "'More' first";
0325     sortListBySection(indexes_morefirst);
0326     qDebug() << "'Uninstalled' first";
0327     sortListBySection(indexes_uninstalledfirst);
0328     qDebug() << "'Uninstalled' first, p0";
0329     sortListBySection(indexes_uninstalled_p0);
0330     qDebug() << "'Uninstalled' first, p1";
0331     sortListBySection(indexes_uninstalled_p1);
0332     qDebug() << "'Uninstalled' first, p2";
0333     sortListBySection(indexes_uninstalled_p2);
0334     qDebug() << "'Uninstalled' first, p3";
0335     sortListBySection(indexes_uninstalled_p3);
0336     qDebug() << "'Uninstalled' first, p4";
0337     sortListBySection(indexes_uninstalled_p4);
0338 }
0339 
0340 void KMoreToolsTest::test_MenuStructureDto_serialize()
0341 {
0342     KmtMenuStructureDto mstruct;
0343 
0344     KmtMenuItemDto ma1;
0345     ma1.id = QStringLiteral("main1");
0346     ma1.menuSection = KMoreTools::MenuSection_Main;
0347     mstruct.list.append(ma1);
0348 
0349     KmtMenuItemDto mo1;
0350     mo1.id = QStringLiteral("more1");
0351     mo1.menuSection = KMoreTools::MenuSection_More;
0352     mstruct.list.append(mo1);
0353 
0354     QString json = mstruct.serialize();
0355     QCOMPARE(json,
0356              QString(_("{\"menuitemlist\":[{\"id\":\"main1\",\"isInstalled\":true,\"menuSection\":\"main\"},{\"id\":\"more1\",\"isInstalled\":true,"
0357                        "\"menuSection\":\"more\"}]}")));
0358 }
0359 
0360 void KMoreToolsTest::test_MenuStructureDto_deserialize()
0361 {
0362     QString jsonStr(
0363         _("{\"menuitemlist\":[{\"id\":\"main1\",\"isInstalled\":true,\"menuSection\":\"main\"},{\"id\":\"more1\",\"isInstalled\":true,\"menuSection\":\"more\"}"
0364           "]}"));
0365     KmtMenuStructureDto mstruct;
0366     mstruct.deserialize(jsonStr);
0367     QCOMPARE(mstruct.list.count(), 2);
0368     KmtMenuItemDto ma1 = mstruct.list[0];
0369     QCOMPARE(ma1.id, _("main1"));
0370     QCOMPARE(ma1.menuSection, KMoreTools::MenuSection_Main);
0371     QCOMPARE(ma1.isInstalled, true);
0372 }
0373 
0374 void KMoreToolsTest::test_KmtUrlUtil_localFileAbsoluteDir()
0375 {
0376     {
0377         auto urlIn = QUrl::fromLocalFile(QStringLiteral("/etc/bash.bashrc"));
0378         QCOMPARE(urlIn.toString(), QString(_("file:///etc/bash.bashrc")));
0379 
0380         auto urlOut = KmtUrlUtil::localFileAbsoluteDir(urlIn);
0381 #ifdef Q_OS_WINDOWS
0382         QCOMPARE(urlOut.toString(), QString(_("file:///C:/etc")));
0383 #else
0384         QCOMPARE(urlOut.toString(), QString(_("file:///etc")));
0385 #endif
0386     }
0387 
0388     {
0389         auto urlIn = QUrl::fromLocalFile(QStringLiteral("/home/u1/dev/kf5/src/kde/applications/dolphin/.reviewboardrc"));
0390         QCOMPARE(urlIn.toString(), QString(_("file:///home/u1/dev/kf5/src/kde/applications/dolphin/.reviewboardrc")));
0391 
0392         auto urlOut = KmtUrlUtil::localFileAbsoluteDir(urlIn);
0393 #ifdef Q_OS_WINDOWS
0394         QCOMPARE(urlOut.toString(), QString(_("file:///C:/home/u1/dev/kf5/src/kde/applications/dolphin")));
0395 #else
0396         QCOMPARE(urlOut.toString(), QString(_("file:///home/u1/dev/kf5/src/kde/applications/dolphin")));
0397 #endif
0398     }
0399 
0400     {
0401         auto urlIn2 = QUrl::fromLocalFile(QStringLiteral("aaa/bbb"));
0402         QCOMPARE(urlIn2.toString(), QString(_("file:aaa/bbb")));
0403     }
0404 }
0405 
0406 QTEST_MAIN(KMoreToolsTest)
0407 
0408 #include "kmoretoolstest.moc"