File indexing completed on 2024-04-21 15:03:05

0001 /*
0002     SPDX-FileCopyrightText: 2014 Alex Richardson <arichardson.kde@gmail.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include <QDebug>
0008 #include <QJsonDocument>
0009 #include <QLocale>
0010 #include <QTest>
0011 
0012 #include <KAboutData>
0013 #include <KPluginMetaData>
0014 
0015 #include <kplugininfo.h>
0016 #include <kservice.h>
0017 
0018 Q_DECLARE_METATYPE(KPluginInfo)
0019 
0020 static const QString pluginName = QStringLiteral("fakeplugin"); // clazy:exclude=non-pod-global-static
0021 
0022 QT_WARNING_PUSH
0023 QT_WARNING_DISABLE_DEPRECATED
0024 
0025 class KPluginInfoTest : public QObject
0026 {
0027     Q_OBJECT
0028 private:
0029     static KPluginInfo withCustomProperty(const KPluginInfo &info)
0030     {
0031         KPluginMetaData metaData = info.toMetaData();
0032         QJsonObject json = metaData.rawData();
0033         json[QStringLiteral("X-Foo-Bar")] = QStringLiteral("Baz");
0034         return KPluginInfo(KPluginMetaData(json, info.libraryPath()));
0035     }
0036 
0037 private Q_SLOTS:
0038     void testLoadDesktop_data()
0039     {
0040         QTest::addColumn<QString>("desktopFilePath");
0041         QTest::addColumn<KPluginInfo>("info");
0042         QTest::addColumn<KPluginInfo>("infoGerman");
0043         QTest::addColumn<QVariant>("customValue");
0044         QTest::addColumn<bool>("translationsWhenLoading");
0045 
0046         QString fakepluginDesktop = QFINDTESTDATA("fakeplugin.desktop");
0047         QVERIFY2(!fakepluginDesktop.isEmpty(), "Could not find fakeplugin.desktop");
0048         QString fakePluginJsonPath = QFINDTESTDATA("fakeplugin_json_new.json");
0049         QVERIFY2(!fakePluginJsonPath.isEmpty(), "Could not find fakeplugin_json_new.json");
0050         QString fakePluginCompatJsonPath = QFINDTESTDATA("fakeplugin_json_old.json");
0051         QVERIFY2(!fakePluginCompatJsonPath.isEmpty(), "Could not find fakeplugin_json_old.json");
0052 
0053         QJsonParseError jsonError;
0054         QFile jsonFile(fakePluginJsonPath);
0055         QVERIFY(jsonFile.open(QFile::ReadOnly));
0056         QJsonObject json = QJsonDocument::fromJson(jsonFile.readAll(), &jsonError).object();
0057         QCOMPARE(jsonError.error, QJsonParseError::NoError);
0058         QVERIFY(!json.isEmpty());
0059         KPluginMetaData metaData(json, fakePluginJsonPath);
0060         QVERIFY(metaData.isValid());
0061         QVERIFY(!metaData.name().isEmpty());
0062         QVERIFY(!metaData.authors().isEmpty());
0063         QVERIFY(!metaData.formFactors().isEmpty());
0064         QCOMPARE(metaData.formFactors(), QStringList() << QStringLiteral("tablet") << QStringLiteral("handset"));
0065         KPluginInfo jsonInfo(KPluginMetaData(json, pluginName));
0066 
0067         QFile compatJsonFile(fakePluginCompatJsonPath);
0068         QVERIFY(compatJsonFile.open(QFile::ReadOnly));
0069         QJsonObject compatJson = QJsonDocument::fromJson(compatJsonFile.readAll(), &jsonError).object();
0070         QCOMPARE(jsonError.error, QJsonParseError::NoError);
0071         QVERIFY(!compatJson.isEmpty());
0072 
0073         // for most constructors translations are performed when the object is constructed and not at runtime!
0074         QLocale::setDefault(QLocale::c());
0075         KPluginInfo info(fakepluginDesktop);
0076 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 0)
0077         KService::Ptr fakepluginService(new KService(fakepluginDesktop));
0078         KPluginInfo infoFromService(fakepluginService);
0079 #endif
0080         KPluginInfo compatJsonInfo(KPluginMetaData(compatJson, pluginName));
0081         QLocale::setDefault(QLocale(QLocale::German, QLocale::Germany));
0082         KPluginInfo infoGerman(fakepluginDesktop);
0083 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 0)
0084         KService::Ptr fakepluginServiceGerman(new KService(fakepluginDesktop));
0085         KPluginInfo infoFromServiceGerman(fakepluginServiceGerman);
0086 #endif
0087         KPluginInfo compatJsonInfoGerman(KPluginMetaData(compatJson, pluginName));
0088         QLocale::setDefault(QLocale::c());
0089 
0090         QTest::ignoreMessage(QtWarningMsg, "\"/this/path/does/not/exist.desktop\" has no desktop group, cannot construct a KPluginInfo object from it.");
0091         QVERIFY(!KPluginInfo(QStringLiteral("/this/path/does/not/exist.desktop")).isValid());
0092 
0093         QTest::newRow("from .desktop") << fakepluginDesktop << info << infoGerman << QVariant() << false;
0094         QTest::newRow("with custom property") << info.libraryPath() << withCustomProperty(info) << withCustomProperty(infoGerman)
0095                                               << QVariant(QStringLiteral("Baz")) << false;
0096 #if KSERVICE_ENABLE_DEPRECATED_SINCE(5, 0)
0097         QTest::newRow("from KService::Ptr") << fakepluginDesktop << infoFromService << infoFromServiceGerman << QVariant() << true;
0098         QTest::newRow("from KService::Ptr + custom property")
0099             << pluginName << withCustomProperty(infoFromService) << withCustomProperty(infoFromServiceGerman) << QVariant(QStringLiteral("Baz")) << true;
0100 #endif
0101         QTest::newRow("from JSON file") << pluginName << jsonInfo << jsonInfo << QVariant() << false;
0102         QTest::newRow("from JSON file + custom property")
0103             << pluginName << withCustomProperty(jsonInfo) << withCustomProperty(jsonInfo) << QVariant(QStringLiteral("Baz")) << false;
0104         QTest::newRow("from JSON file (compatibility)") << pluginName << compatJsonInfo << compatJsonInfoGerman << QVariant() << true;
0105         QTest::newRow("from JSON file (compatibility) + custom property")
0106             << pluginName << withCustomProperty(compatJsonInfo) << withCustomProperty(compatJsonInfoGerman) << QVariant(QStringLiteral("Baz")) << true;
0107     }
0108 
0109     void testLoadDesktop()
0110     {
0111         QFETCH(KPluginInfo, info);
0112         QFETCH(KPluginInfo, infoGerman);
0113         QFETCH(QVariant, customValue);
0114         QFETCH(QString, desktopFilePath);
0115         QFETCH(bool, translationsWhenLoading);
0116 
0117         QVERIFY(info.isValid());
0118         QVERIFY(infoGerman.isValid());
0119         // check the translatable keys first
0120         if (translationsWhenLoading) {
0121             // translations are only performed once in the constructor, not when requesting them
0122             QCOMPARE(info.comment(), QStringLiteral("Test Plugin Spy"));
0123             QCOMPARE(infoGerman.comment(), QStringLiteral("Test-Spionagemodul"));
0124             QCOMPARE(info.name(), QStringLiteral("NSA Plugin"));
0125             QCOMPARE(infoGerman.name(), QStringLiteral("NSA-Modul"));
0126         } else {
0127             // translations work correctly here since they are not fixed at load time
0128             QLocale::setDefault(QLocale::c());
0129             QCOMPARE(info.name(), QStringLiteral("NSA Plugin"));
0130             QCOMPARE(infoGerman.name(), QStringLiteral("NSA Plugin"));
0131             QCOMPARE(info.comment(), QStringLiteral("Test Plugin Spy"));
0132             QCOMPARE(infoGerman.comment(), QStringLiteral("Test Plugin Spy"));
0133             QLocale::setDefault(QLocale(QLocale::German, QLocale::Germany));
0134             QCOMPARE(info.comment(), QStringLiteral("Test-Spionagemodul"));
0135             QCOMPARE(infoGerman.comment(), QStringLiteral("Test-Spionagemodul"));
0136             QCOMPARE(info.name(), QStringLiteral("NSA-Modul"));
0137             QCOMPARE(infoGerman.name(), QStringLiteral("NSA-Modul"));
0138         }
0139 
0140         QCOMPARE(info.author(), QString::fromUtf8("Sebastian Kügler"));
0141         QCOMPARE(info.category(), QStringLiteral("Examples"));
0142 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79) && KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 79)
0143         if (!info.dependencies().isEmpty()) {
0144             qWarning() << "Got dependencies" << info.dependencies();
0145         }
0146         QCOMPARE(info.dependencies(), QStringList());
0147 #endif
0148         QCOMPARE(info.email(), QStringLiteral("sebas@kde.org"));
0149         QCOMPARE(info.entryPath(), desktopFilePath);
0150         QCOMPARE(info.icon(), QStringLiteral("preferences-system-time"));
0151         QCOMPARE(info.isHidden(), false);
0152         QCOMPARE(info.isPluginEnabled(), false);
0153         QCOMPARE(info.isPluginEnabledByDefault(), true);
0154         QCOMPARE(info.libraryPath(), pluginName);
0155         QCOMPARE(info.license(), QStringLiteral("LGPL"));
0156         QCOMPARE(info.pluginName(), pluginName);
0157         // KService/KPluginInfo merges X-KDE-ServiceTypes and MimeTypes
0158         QCOMPARE(info.serviceTypes(), QStringList() << QStringLiteral("KService/NSA") << QStringLiteral("text/plain") << QStringLiteral("image/png"));
0159 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 70)
0160         if (!info.service()) {
0161 #endif
0162             // KService does not include X-My-Custom-Property since there is no service type installed that defines it
0163             QCOMPARE(info.property(QStringLiteral("X-My-Custom-Property")), QVariant(QStringLiteral("foo")));
0164 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 70)
0165         }
0166 #endif
0167         // Now check that converting to KPluginMetaData has the separation
0168         KPluginMetaData asMetaData = info.toMetaData();
0169         QCOMPARE(asMetaData.serviceTypes(), QStringList() << QStringLiteral("KService/NSA"));
0170         QCOMPARE(asMetaData.mimeTypes(), QStringList() << QStringLiteral("text/plain") << QStringLiteral("image/png"));
0171 
0172         QCOMPARE(info.version(), QStringLiteral("1.0"));
0173         QCOMPARE(info.website(), QStringLiteral("http://kde.org/"));
0174 
0175         QCOMPARE(info.property(QStringLiteral("X-Foo-Bar")), customValue);
0176     }
0177 
0178     void testToMetaData()
0179     {
0180         QString fakepluginDesktop = QFINDTESTDATA("fakeplugin.desktop");
0181         QVERIFY2(!fakepluginDesktop.isEmpty(), "Could not find fakeplugin.desktop");
0182         KPluginInfo info = withCustomProperty(KPluginInfo(fakepluginDesktop));
0183         QVERIFY(info.isValid());
0184         KPluginMetaData meta = info.toMetaData();
0185         QVERIFY(meta.isValid());
0186 
0187         // check the translatable keys first
0188         // as of 5.7 translations are performed at runtime and not when the file is read
0189         QLocale::setDefault(QLocale::c());
0190         QCOMPARE(meta.description(), QStringLiteral("Test Plugin Spy"));
0191         QCOMPARE(meta.name(), QStringLiteral("NSA Plugin"));
0192         QLocale::setDefault(QLocale(QLocale::German));
0193         QCOMPARE(meta.description(), QStringLiteral("Test-Spionagemodul"));
0194         QCOMPARE(meta.name(), QStringLiteral("NSA-Modul"));
0195         QLocale::setDefault(QLocale::c());
0196 
0197         QCOMPARE(meta.authors().size(), 1);
0198         QCOMPARE(meta.authors().at(0).name(), QString::fromUtf8("Sebastian Kügler"));
0199         QCOMPARE(meta.authors().at(0).emailAddress(), QStringLiteral("sebas@kde.org"));
0200         QCOMPARE(meta.category(), QStringLiteral("Examples"));
0201 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79) && KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 79)
0202         QCOMPARE(meta.dependencies(), QStringList());
0203 #endif
0204         QCOMPARE(meta.fileName(), pluginName);
0205         QCOMPARE(meta.pluginId(), pluginName);
0206         QCOMPARE(meta.iconName(), QStringLiteral("preferences-system-time"));
0207         QCOMPARE(meta.isEnabledByDefault(), true);
0208         QCOMPARE(meta.license(), QStringLiteral("LGPL"));
0209         QCOMPARE(meta.serviceTypes(), QStringList() << QStringLiteral("KService/NSA"));
0210         QCOMPARE(meta.formFactors(), QStringList() << QStringLiteral("tablet") << QStringLiteral("handset"));
0211         QCOMPARE(meta.version(), QStringLiteral("1.0"));
0212         QCOMPARE(meta.website(), QStringLiteral("http://kde.org/"));
0213 
0214         // also test the static version
0215         QCOMPARE(meta, KPluginInfo::toMetaData(info));
0216 
0217         // make sure custom values are also retained
0218         QCOMPARE(info.property(QStringLiteral("X-Foo-Bar")), QVariant(QStringLiteral("Baz")));
0219         QCOMPARE(meta.rawData().value(QStringLiteral("X-Foo-Bar")).toString(), QStringLiteral("Baz"));
0220 
0221         KPluginInfo::List srcList = KPluginInfo::List() << info << info;
0222         QVector<KPluginMetaData> convertedList = KPluginInfo::toMetaData(srcList);
0223         QCOMPARE(convertedList.size(), 2);
0224         QCOMPARE(convertedList[0], meta);
0225         QCOMPARE(convertedList[1], meta);
0226     }
0227 
0228     void testFromMetaData()
0229     {
0230         QJsonParseError e;
0231         QJsonObject jo = QJsonDocument::fromJson(
0232                              "{\n"
0233                              " \"KPlugin\": {\n"
0234                              " \"Name\": \"NSA Plugin\",\n"
0235                              " \"Name[de]\": \"NSA-Modul\",\n"
0236                              " \"Description\": \"Test Plugin Spy\",\n"
0237                              " \"Description[de]\": \"Test-Spionagemodul\",\n"
0238                              " \"Icon\": \"preferences-system-time\",\n"
0239                              " \"Authors\": { \"Name\": \"Sebastian Kügler\", \"Email\": \"sebas@kde.org\" },\n"
0240                              " \"Category\": \"Examples\",\n"
0241 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79) && KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 79)
0242                              " \"Dependencies\": [],\n"
0243 #endif
0244                              " \"EnabledByDefault\": \"true\",\n"
0245                              " \"License\": \"LGPL\",\n"
0246                              " \"Id\": \"fakeplugin\",\n" // not strictly required
0247                              " \"Version\": \"1.0\",\n"
0248                              " \"Website\": \"http://kde.org/\",\n"
0249                              " \"ServiceTypes\": [\"KService/NSA\"],\n"
0250                              " \"FormFactors\": [\"tablet\", \"handset\"]\n"
0251                              " },\n"
0252                              " \"X-Foo-Bar\": \"Baz\"\n"
0253                              "}",
0254                              &e)
0255                              .object();
0256         QCOMPARE(e.error, QJsonParseError::NoError);
0257         KPluginMetaData meta(jo, pluginName);
0258 
0259         QLocale::setDefault(QLocale::c());
0260         KPluginInfo info = KPluginInfo::fromMetaData(meta);
0261         QLocale::setDefault(QLocale(QLocale::German, QLocale::Germany));
0262         KPluginInfo infoGerman = KPluginInfo::fromMetaData(meta);
0263         QLocale::setDefault(QLocale::c());
0264 
0265         // translations work correctly here since they are not fixed at load time
0266         QCOMPARE(info.name(), QStringLiteral("NSA Plugin"));
0267         QCOMPARE(infoGerman.name(), QStringLiteral("NSA Plugin"));
0268         QCOMPARE(info.comment(), QStringLiteral("Test Plugin Spy"));
0269         QCOMPARE(infoGerman.comment(), QStringLiteral("Test Plugin Spy"));
0270         QLocale::setDefault(QLocale(QLocale::German, QLocale::Germany));
0271         QCOMPARE(info.comment(), QStringLiteral("Test-Spionagemodul"));
0272         QCOMPARE(infoGerman.comment(), QStringLiteral("Test-Spionagemodul"));
0273         QCOMPARE(info.name(), QStringLiteral("NSA-Modul"));
0274         QCOMPARE(infoGerman.name(), QStringLiteral("NSA-Modul"));
0275         QLocale::setDefault(QLocale::c());
0276 
0277         QCOMPARE(info.author(), QString::fromUtf8("Sebastian Kügler"));
0278         QCOMPARE(info.category(), QStringLiteral("Examples"));
0279 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79) && KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 79)
0280         QCOMPARE(info.dependencies(), QStringList());
0281 #endif
0282         QCOMPARE(info.email(), QStringLiteral("sebas@kde.org"));
0283         QCOMPARE(info.entryPath(), pluginName);
0284         QCOMPARE(info.icon(), QStringLiteral("preferences-system-time"));
0285         QCOMPARE(info.isHidden(), false);
0286         QCOMPARE(info.isPluginEnabled(), false);
0287         QCOMPARE(info.isPluginEnabledByDefault(), true);
0288         QCOMPARE(info.libraryPath(), pluginName);
0289         QCOMPARE(info.license(), QStringLiteral("LGPL"));
0290         QCOMPARE(info.pluginName(), pluginName);
0291         QCOMPARE(info.serviceTypes(), QStringList() << QStringLiteral("KService/NSA"));
0292         QCOMPARE(info.version(), QStringLiteral("1.0"));
0293         QCOMPARE(info.website(), QStringLiteral("http://kde.org/"));
0294         QCOMPARE(info.toMetaData().formFactors(), QStringList() << QStringLiteral("tablet") << QStringLiteral("handset"));
0295         QCOMPARE(info.formFactors(), QStringList() << QStringLiteral("tablet") << QStringLiteral("handset"));
0296 
0297         // make sure custom values are also retained
0298         QCOMPARE(meta.rawData().value(QStringLiteral("X-Foo-Bar")).toString(), QStringLiteral("Baz"));
0299         QCOMPARE(info.property(QStringLiteral("X-Foo-Bar")), QVariant(QStringLiteral("Baz")));
0300 
0301         QVector<KPluginMetaData> srcList = QVector<KPluginMetaData>() << meta;
0302         KPluginInfo::List convertedList = KPluginInfo::fromMetaData(srcList);
0303         QCOMPARE(convertedList.size(), 1);
0304         // KPluginInfo::operator== compares identity of the d-pointer -> manual structural comparison
0305         QCOMPARE(convertedList[0].comment(), info.comment());
0306         QCOMPARE(convertedList[0].name(), info.name());
0307         QCOMPARE(convertedList[0].author(), info.author());
0308         QCOMPARE(convertedList[0].category(), info.category());
0309 #if KSERVICE_BUILD_DEPRECATED_SINCE(5, 79) && KCOREADDONS_BUILD_DEPRECATED_SINCE(5, 79)
0310         QCOMPARE(convertedList[0].dependencies(), info.dependencies());
0311 #endif
0312         QCOMPARE(convertedList[0].email(), info.email());
0313         QCOMPARE(convertedList[0].entryPath(), info.entryPath());
0314         QCOMPARE(convertedList[0].icon(), info.icon());
0315         QCOMPARE(convertedList[0].isHidden(), info.isHidden());
0316         QCOMPARE(convertedList[0].isPluginEnabled(), info.isPluginEnabled());
0317         QCOMPARE(convertedList[0].isPluginEnabledByDefault(), info.isPluginEnabledByDefault());
0318         QCOMPARE(convertedList[0].libraryPath(), info.libraryPath());
0319         QCOMPARE(convertedList[0].license(), info.license());
0320         QCOMPARE(convertedList[0].pluginName(), info.pluginName());
0321         QCOMPARE(convertedList[0].serviceTypes(), info.serviceTypes());
0322         QCOMPARE(convertedList[0].version(), info.version());
0323         QCOMPARE(convertedList[0].website(), info.website());
0324         QCOMPARE(convertedList[0].formFactors(), info.formFactors());
0325     }
0326 };
0327 
0328 QTEST_MAIN(KPluginInfoTest)
0329 
0330 #include "kplugininfotest.moc"