File indexing completed on 2024-04-21 03:56:30

0001 /*
0002     SPDX-FileCopyrightText: 2007 Aaron Seigo <aseigo@kde.org>
0003     SPDX-FileCopyrightText: 2014 Marco Martin <mart@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "packagestructuretest.h"
0009 
0010 #include <KLocalizedString>
0011 #include <QDebug>
0012 
0013 #include "packageloader.h"
0014 #include "packagestructure.h"
0015 #include "private/utils.h"
0016 
0017 class NoPrefixes : public KPackage::Package
0018 {
0019 public:
0020     explicit NoPrefixes()
0021         : KPackage::Package(new KPackage::PackageStructure)
0022     {
0023         setContentsPrefixPaths(QStringList());
0024         addDirectoryDefinition("bin", QStringLiteral("bin"));
0025         addFileDefinition("MultiplePaths", QStringLiteral("first"));
0026         addFileDefinition("MultiplePaths", QStringLiteral("second"));
0027         setPath(QStringLiteral("/"));
0028     }
0029 };
0030 
0031 class Wallpaper : public KPackage::PackageStructure
0032 {
0033     Q_OBJECT
0034 public:
0035     void initPackage(KPackage::Package *package) override
0036     {
0037         package->addDirectoryDefinition("images", QStringLiteral("images/"));
0038 
0039         const QStringList mimetypes{QStringLiteral("image/svg"), QStringLiteral("image/png"), QStringLiteral("image/jpeg"), QStringLiteral("image/jpg")};
0040         package->setMimeTypes("images", mimetypes);
0041 
0042         package->setRequired("images", true);
0043         package->addFileDefinition("screenshot", QStringLiteral("screenshot.png"));
0044         package->setAllowExternalPaths(true);
0045     }
0046     void pathChanged(KPackage::Package *package) override
0047     {
0048         static bool guard = false;
0049 
0050         if (guard) {
0051             return;
0052         }
0053 
0054         guard = true;
0055         QString ppath = package->path();
0056         if (ppath.endsWith('/')) {
0057             ppath.chop(1);
0058             if (!QFile::exists(ppath)) {
0059                 ppath = package->path();
0060             }
0061         }
0062 
0063         QFileInfo info(ppath);
0064         const bool isFullPackage = info.isDir();
0065         package->removeDefinition("preferred");
0066         package->setRequired("images", isFullPackage);
0067 
0068         if (isFullPackage) {
0069             package->setContentsPrefixPaths(QStringList{QStringLiteral("contents/")});
0070         } else {
0071             package->addFileDefinition("screenshot", info.fileName());
0072             package->addFileDefinition("preferred", info.fileName());
0073             package->setContentsPrefixPaths(QStringList());
0074             package->setPath(info.path());
0075         }
0076 
0077         guard = false;
0078     }
0079 };
0080 
0081 class SimpleContent : public KPackage::PackageStructure
0082 {
0083     Q_OBJECT
0084 public:
0085     void initPackage(KPackage::Package *package) override
0086     {
0087         package->addDirectoryDefinition("ui", QStringLiteral("ui/"));
0088     }
0089     void pathChanged(KPackage::Package *package) override
0090     {
0091         if (!package->metadata().isValid()) {
0092             return;
0093         }
0094         if (readKPackageType(package->metadata()) == QStringLiteral("KPackage/CustomContent")) {
0095             package->addFileDefinition("customcontentfile", QStringLiteral("customcontent/CustomContentFile.qml"));
0096         } else {
0097             package->removeDefinition("customcontentfile");
0098         }
0099     }
0100 };
0101 
0102 void PackageStructureTest::initTestCase()
0103 {
0104     m_packagePath = QFINDTESTDATA("data/testpackage");
0105     ps = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/GenericQML"));
0106     ps.setPath(m_packagePath);
0107 }
0108 
0109 void PackageStructureTest::validStructures()
0110 {
0111     QVERIFY(ps.hasValidStructure());
0112     QVERIFY(!KPackage::Package().hasValidStructure());
0113     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).hasValidStructure());
0114 }
0115 
0116 void PackageStructureTest::validPackages()
0117 {
0118     QVERIFY(ps.isValid());
0119     QVERIFY(!KPackage::Package().isValid());
0120     QVERIFY(!KPackage::PackageLoader::self()->loadPackage(QStringLiteral("doesNotExist")).isValid());
0121     QVERIFY(NoPrefixes().isValid());
0122 
0123     KPackage::Package p = KPackage::PackageLoader::self()->loadPackage(QStringLiteral("KPackage/Generic"));
0124     p.addFileDefinition("mainscript", QStringLiteral("ui/main.qml"));
0125     QVERIFY(!p.isValid());
0126     p.setPath(QStringLiteral("/does/not/exist"));
0127     QVERIFY(!p.isValid());
0128     p.setPath(ps.path());
0129     QVERIFY(p.isValid());
0130 }
0131 
0132 void PackageStructureTest::wallpaperPackage()
0133 {
0134     KPackage::Package p(new Wallpaper);
0135     p.setPath(m_packagePath);
0136     QVERIFY(p.isValid());
0137 
0138     KPackage::Package p2(new Wallpaper);
0139     p2.setPath(m_packagePath + "/contents/images/empty.png");
0140     QVERIFY(p2.isValid());
0141 }
0142 
0143 void PackageStructureTest::mutateAfterCopy()
0144 {
0145     const bool mainscriptRequired = ps.isRequired("mainscript");
0146     const QStringList imageMimeTypes = ps.mimeTypes("images");
0147     const QStringList defaultMimeTypes = ps.mimeTypes("translations");
0148     const QString packageRoot = ps.defaultPackageRoot();
0149     const bool externalPaths = ps.allowExternalPaths();
0150     const QStringList contentsPrefixPaths = ps.contentsPrefixPaths();
0151     const QList<QByteArray> files = ps.files();
0152     const QList<QByteArray> dirs = ps.directories();
0153 
0154     KPackage::Package copy(ps);
0155 
0156     copy.setRequired("mainscript", !mainscriptRequired);
0157     QCOMPARE(ps.isRequired("mainscript"), mainscriptRequired);
0158     QCOMPARE(copy.isRequired("mainscript"), !mainscriptRequired);
0159 
0160     copy = ps;
0161     const QString copyPackageRoot = packageRoot + "more/";
0162     copy.setDefaultPackageRoot(copyPackageRoot);
0163     QCOMPARE(ps.defaultPackageRoot(), packageRoot);
0164     QCOMPARE(copy.defaultPackageRoot(), copyPackageRoot);
0165 
0166     copy = ps;
0167     copy.setAllowExternalPaths(!externalPaths);
0168     QCOMPARE(ps.allowExternalPaths(), externalPaths);
0169     QCOMPARE(copy.allowExternalPaths(), !externalPaths);
0170 
0171     copy = ps;
0172     const QStringList copyContentsPrefixPaths = QStringList(contentsPrefixPaths) << QStringLiteral("more/");
0173     copy.setContentsPrefixPaths(copyContentsPrefixPaths);
0174     QCOMPARE(ps.contentsPrefixPaths(), contentsPrefixPaths);
0175     QCOMPARE(copy.contentsPrefixPaths(), copyContentsPrefixPaths);
0176 
0177     copy = ps;
0178     copy.addFileDefinition("nonsense", QStringLiteral("foobar"));
0179     QCOMPARE(ps.files(), files);
0180     QVERIFY(ps.files() != copy.files());
0181 
0182     copy = ps;
0183     copy.addDirectoryDefinition("nonsense", QStringLiteral("foobar"));
0184     QCOMPARE(ps.directories(), dirs);
0185     QVERIFY(ps.directories() != copy.directories());
0186 
0187     copy = ps;
0188     copy.removeDefinition("mainscript");
0189     QCOMPARE(ps.files(), files);
0190     QVERIFY(ps.files() != copy.files());
0191 
0192     copy = ps;
0193     QVERIFY(!imageMimeTypes.isEmpty());
0194     const QStringList copyMimeTypes(imageMimeTypes.first());
0195     copy.setMimeTypes("images", copyMimeTypes);
0196     QCOMPARE(ps.mimeTypes("images"), imageMimeTypes);
0197     QCOMPARE(copy.mimeTypes("images"), copyMimeTypes);
0198 
0199     copy = ps;
0200     const QStringList copyDefaultMimeTypes = QStringList(defaultMimeTypes) << QStringLiteral("rubbish");
0201     copy.setDefaultMimeTypes(copyDefaultMimeTypes);
0202     QCOMPARE(ps.mimeTypes("translations"), defaultMimeTypes);
0203     QCOMPARE(copy.mimeTypes("translations"), copyDefaultMimeTypes);
0204 }
0205 
0206 void PackageStructureTest::emptyContentsPrefix()
0207 {
0208     NoPrefixes package;
0209     QString path(package.filePath("bin", QStringLiteral("ls")));
0210     if (QFileInfo::exists(QStringLiteral("/bin/ls"))) { // not Windows
0211         QCOMPARE(path, QStringLiteral("/bin/ls"));
0212     }
0213 }
0214 
0215 void PackageStructureTest::directories()
0216 {
0217     const QList<QByteArray> dirs{
0218         "config",
0219         "data",
0220         "images",
0221         "theme",
0222         "scripts",
0223         "translations",
0224         "ui",
0225     };
0226 
0227     const QList<QByteArray> psDirs = ps.directories();
0228 
0229     QCOMPARE(dirs.count(), psDirs.count());
0230 
0231     for (const char *dir : psDirs) {
0232         bool found = false;
0233         for (const char *check : std::as_const(dirs)) {
0234             if (qstrcmp(dir, check)) {
0235                 found = true;
0236                 break;
0237             }
0238         }
0239         QVERIFY(found);
0240     }
0241 
0242     for (const char *dir : std::as_const(dirs)) {
0243         bool found = false;
0244         for (const char *check : psDirs) {
0245             if (qstrcmp(dir, check)) {
0246                 found = true;
0247                 break;
0248             }
0249         }
0250         QVERIFY(found);
0251     }
0252 }
0253 
0254 void PackageStructureTest::requiredDirectories()
0255 {
0256     QList<QByteArray> dirs;
0257     QCOMPARE(ps.requiredDirectories(), dirs);
0258 }
0259 
0260 void PackageStructureTest::files()
0261 {
0262     const QList<QByteArray> files{
0263         "mainconfigui",
0264         "mainconfigxml",
0265         "mainscript",
0266     };
0267 
0268     const QList<QByteArray> psFiles = ps.files();
0269 
0270     for (const char *file : psFiles) {
0271         bool found = false;
0272         for (const char *check : std::as_const(files)) {
0273             if (qstrcmp(file, check)) {
0274                 found = true;
0275                 break;
0276             }
0277         }
0278         QVERIFY(found);
0279     }
0280 }
0281 
0282 void PackageStructureTest::requiredFiles()
0283 {
0284     const QList<QByteArray> files{"mainscript"};
0285     const QList<QByteArray> psFiles = ps.requiredFiles();
0286     QCOMPARE(files, psFiles);
0287 }
0288 
0289 void PackageStructureTest::path()
0290 {
0291     QCOMPARE(ps.filePath("images"), QDir(m_packagePath + QLatin1String("/contents/images")).canonicalPath());
0292     QCOMPARE(ps.filePath("theme"), QString());
0293     QCOMPARE(ps.filePath("mainscript"), QFileInfo(m_packagePath + QLatin1String("/contents/ui/main.qml")).canonicalFilePath());
0294 }
0295 
0296 void PackageStructureTest::required()
0297 {
0298     QVERIFY(ps.isRequired("mainscript"));
0299 }
0300 
0301 void PackageStructureTest::mimeTypes()
0302 {
0303     const QStringList mimeTypes{QStringLiteral("image/svg+xml"), QStringLiteral("image/png"), QStringLiteral("image/jpeg")};
0304     QCOMPARE(ps.mimeTypes("images"), mimeTypes);
0305     QCOMPARE(ps.mimeTypes("theme"), mimeTypes);
0306 }
0307 
0308 void PackageStructureTest::customContent()
0309 {
0310     KPackage::Package p(new SimpleContent);
0311     p.setPath(QFINDTESTDATA("data/simplecontent"));
0312     QVERIFY(p.isValid());
0313     QCOMPARE(p.filePath("customcontentfile"), QString());
0314 
0315     p.setPath(QFINDTESTDATA("data/customcontent"));
0316     const QString expected = QFINDTESTDATA("data/customcontent") + "/contents/customcontent/CustomContentFile.qml";
0317     QCOMPARE(p.filePath("customcontentfile"), expected);
0318     QVERIFY(p.isValid());
0319 
0320     p.setPath(QFINDTESTDATA("data/simplecontent"));
0321     QVERIFY(p.isValid());
0322     QCOMPARE(p.filePath("customcontentfile"), QString());
0323 }
0324 
0325 QTEST_MAIN(PackageStructureTest)
0326 
0327 #include "moc_packagestructuretest.cpp"
0328 #include "packagestructuretest.moc"