Warning, file /frameworks/kpackage/autotests/plasmoidpackagetest.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: 2007 Bertjan Broeksema <b.broeksema@kdemail.net> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "plasmoidpackagetest.h" 0008 #include "../src/kpackage/config-package.h" 0009 #include "../src/kpackage/private/versionparser.cpp" 0010 0011 #include <KJob> 0012 #include <QDir> 0013 #include <QFile> 0014 #include <QSignalSpy> 0015 #include <QStandardPaths> 0016 #include <kzip.h> 0017 0018 #include <QDebug> 0019 #include <QJsonDocument> 0020 #include <QJsonObject> 0021 0022 #include "packageloader.h" 0023 #include "packagestructures/plasmoidstructure.h" 0024 #include "private/utils.h" 0025 0026 void PlasmoidPackageTest::initTestCase() 0027 { 0028 QStandardPaths::setTestModeEnabled(true); 0029 } 0030 0031 void PlasmoidPackageTest::init() 0032 { 0033 qDebug() << "PlasmoidPackage::init()"; 0034 m_package = QStringLiteral("Package"); 0035 m_packageRoot = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/packageRoot"; 0036 m_defaultPackage = KPackage::Package(new KPackage::PlasmoidPackage); 0037 cleanup(); // to prevent previous runs from interfering with this one 0038 } 0039 0040 void PlasmoidPackageTest::cleanup() 0041 { 0042 qDebug() << "cleaning up"; 0043 // Clean things up. 0044 QDir(m_packageRoot).removeRecursively(); 0045 } 0046 0047 void PlasmoidPackageTest::createTestPackage(const QString &packageName, const QString &version) 0048 { 0049 qDebug() << "Create test package" << m_packageRoot; 0050 QDir pRoot(m_packageRoot); 0051 // Create the root and package dir. 0052 if (!pRoot.exists()) { 0053 QVERIFY(QDir().mkpath(m_packageRoot)); 0054 } 0055 0056 // Create the package dir 0057 QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName)); 0058 qDebug() << "Created" << (m_packageRoot + "/" + packageName); 0059 0060 // Create the metadata.json file 0061 QFile file(m_packageRoot + "/" + packageName + "/metadata.json"); 0062 0063 QVERIFY(file.open(QIODevice::WriteOnly)); 0064 0065 QJsonObject kplugin; 0066 kplugin.insert(QLatin1String("Id"), packageName); 0067 kplugin.insert(QLatin1String("Name"), packageName); 0068 kplugin.insert(QLatin1String("Version"), version); 0069 QJsonObject root{{QLatin1String("KPlugin"), kplugin}}; 0070 0071 QTextStream out(&file); 0072 file.write(QJsonDocument(root).toJson()); 0073 file.flush(); 0074 file.close(); 0075 0076 qDebug() << "OUT: " << packageName; 0077 0078 // Create the ui dir. 0079 QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName + "/contents/ui")); 0080 0081 // Create the main file. 0082 file.setFileName(m_packageRoot + "/" + packageName + "/contents/ui/main.qml"); 0083 QVERIFY(file.open(QIODevice::WriteOnly)); 0084 0085 out << "THIS IS A PLASMOID SCRIPT....."; 0086 file.flush(); 0087 file.close(); 0088 0089 qDebug() << "THIS IS A PLASMOID SCRIPT THING"; 0090 // Now we have a minimal plasmoid package which is valid. Let's add some 0091 // files to it for test purposes. 0092 0093 // Create the images dir. 0094 QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName + "/contents/images")); 0095 file.setFileName(m_packageRoot + "/" + packageName + "/contents/images/image-1.svg"); 0096 0097 QVERIFY(file.open(QIODevice::WriteOnly)); 0098 0099 out << "<svg>This is a test image</svg>"; 0100 file.flush(); 0101 file.close(); 0102 0103 file.setFileName(m_packageRoot + "/" + packageName + "/contents/images/image-2.svg"); 0104 0105 QVERIFY(file.open(QIODevice::WriteOnly)); 0106 0107 out.setDevice(&file); 0108 out << "<svg>This is another test image</svg>"; 0109 file.flush(); 0110 file.close(); 0111 0112 // Create the scripts dir. 0113 QVERIFY(QDir().mkpath(m_packageRoot + "/" + packageName + "/contents/code")); 0114 0115 // Create 2 js files 0116 file.setFileName(m_packageRoot + "/" + packageName + "/contents/code/script.js"); 0117 QVERIFY(file.open(QIODevice::WriteOnly)); 0118 0119 out << "THIS IS A SCRIPT....."; 0120 file.flush(); 0121 file.close(); 0122 } 0123 0124 void PlasmoidPackageTest::isValid() 0125 { 0126 KPackage::Package *p = new KPackage::Package(m_defaultPackage); 0127 p->setPath(m_packageRoot + '/' + m_package); 0128 #ifndef NDEBUG 0129 qDebug() << "package path is" << p->path(); 0130 #endif 0131 0132 // A PlasmoidPackage is valid when: 0133 // - The package root exists. 0134 // - The package root consists an file named "ui/main.qml" 0135 QVERIFY(!p->isValid()); 0136 0137 // Create the root and package dir. 0138 QVERIFY(QDir().mkpath(m_packageRoot)); 0139 QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package)); 0140 0141 // Should still be invalid. 0142 delete p; 0143 p = new KPackage::Package(m_defaultPackage); 0144 p->setPath(m_packageRoot + '/' + m_package); 0145 QVERIFY(!p->isValid()); 0146 0147 // Create the metadata.json file. 0148 QFile file(m_packageRoot + "/" + m_package + "/metadata.json"); 0149 QVERIFY(file.open(QIODevice::WriteOnly)); 0150 0151 QTextStream out(&file); 0152 out << "[Desktop Entry]\n"; 0153 out << "Name=test\n"; 0154 out << "Description=Just a test desktop file"; 0155 file.flush(); 0156 file.close(); 0157 0158 // Create the ui dir. 0159 QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package + "/contents/ui")); 0160 0161 // No main file yet so should still be invalid. 0162 delete p; 0163 p = new KPackage::Package(m_defaultPackage); 0164 p->setPath(m_packageRoot + '/' + m_package); 0165 QVERIFY(!p->isValid()); 0166 0167 // Create the main file. 0168 file.setFileName(m_packageRoot + "/" + m_package + "/contents/ui/main.qml"); 0169 QVERIFY(file.open(QIODevice::WriteOnly)); 0170 0171 out.setDevice(&file); 0172 out << "THIS IS A PLASMOID SCRIPT.....\n"; 0173 file.flush(); 0174 file.close(); 0175 0176 file.setPermissions(QFile::ReadUser | QFile::WriteUser); 0177 // Main file exists so should be valid now. 0178 delete p; 0179 p = new KPackage::Package(m_defaultPackage); 0180 p->setPath(m_packageRoot + '/' + m_package); 0181 QVERIFY(p->isValid()); 0182 #if KPACKAGE_ENABLE_DEPRECATED_SINCE(5, 21) 0183 QCOMPARE(p->contentsHash(), QStringLiteral("a41160c6a763ea505c95bee12a7fc87952a61cf1")); 0184 #endif 0185 QCOMPARE(p->cryptographicHash(QCryptographicHash::Sha1), QByteArrayLiteral("a41160c6a763ea505c95bee12a7fc87952a61cf1")); 0186 delete p; 0187 } 0188 0189 void PlasmoidPackageTest::filePath() 0190 { 0191 return; 0192 // Package::filePath() returns 0193 // - {package_root}/{package_name}/path/to/file if the file exists 0194 // - QString() otherwise. 0195 KPackage::Package *p = new KPackage::Package(m_defaultPackage); 0196 p->setPath(m_packageRoot + '/' + m_package); 0197 0198 QCOMPARE(p->filePath("scripts", QStringLiteral("main")), QString()); 0199 0200 QVERIFY(QDir().mkpath(m_packageRoot + "/" + m_package + "/contents/ui/main.qml")); 0201 QFile file(m_packageRoot + "/" + m_package + "/contents/ui/main.qml"); 0202 QVERIFY(file.open(QIODevice::WriteOnly)); 0203 0204 QTextStream out(&file); 0205 out << "THIS IS A PLASMOID SCRIPT....."; 0206 file.flush(); 0207 file.close(); 0208 0209 // The package is valid by now so a path for code/main should get returned. 0210 delete p; 0211 p = new KPackage::Package(m_defaultPackage); 0212 p->setPath(m_packageRoot + '/' + m_package); 0213 0214 const QString path = QFileInfo(m_packageRoot + "/" + m_package + "/contents/ui/main.qml").canonicalFilePath(); 0215 0216 // Two ways to get the same info. 0217 // 1. Give the file type which refers to a class of files (a directory) in 0218 // the package structure and the file name. 0219 // 2. Give the file type which refers to a file in the package structure. 0220 // 0221 // NOTE: scripts, main and mainscript are defined in packages.cpp and are 0222 // specific for a PlasmoidPackage. 0223 QCOMPARE(p->filePath("scripts", QStringLiteral("main")), path); 0224 QCOMPARE(p->filePath("mainscript"), path); 0225 delete p; 0226 } 0227 0228 void PlasmoidPackageTest::entryList() 0229 { 0230 // Create a package named @p packageName which is valid and has some images. 0231 createTestPackage(m_package, QStringLiteral("1.1")); 0232 0233 // Create a package object and verify that it is valid. 0234 KPackage::Package *p = new KPackage::Package(m_defaultPackage); 0235 p->setPath(m_packageRoot + '/' + m_package); 0236 QVERIFY(p->isValid()); 0237 0238 // Now we have a valid package that should contain the following files in 0239 // given filetypes: 0240 // fileTye - Files 0241 // scripts - {"script.js"} 0242 // images - {"image-1.svg", "image-2.svg"} 0243 QStringList files = p->entryList("scripts"); 0244 QCOMPARE(files.size(), 1); 0245 QVERIFY(files.contains(QStringLiteral("script.js"))); 0246 0247 files = p->entryList("images"); 0248 QCOMPARE(files.size(), 2); 0249 QVERIFY(files.contains(QStringLiteral("image-1.svg"))); 0250 QVERIFY(files.contains(QStringLiteral("image-2.svg"))); 0251 delete p; 0252 } 0253 0254 void PlasmoidPackageTest::createAndInstallPackage() 0255 { 0256 qDebug() << " "; 0257 qDebug() << " CreateAndInstall "; 0258 createTestPackage(QStringLiteral("plasmoid_to_package"), QStringLiteral("1.1")); 0259 const QString packagePath = m_packageRoot + '/' + "testpackage.plasmoid"; 0260 0261 KZip creator(packagePath); 0262 QVERIFY(creator.open(QIODevice::WriteOnly)); 0263 creator.addLocalDirectory(m_packageRoot + '/' + "plasmoid_to_package", QStringLiteral(".")); 0264 creator.close(); 0265 QDir rootDir(m_packageRoot + "/plasmoid_to_package"); 0266 rootDir.removeRecursively(); 0267 0268 QVERIFY2(QFile::exists(packagePath), qPrintable(packagePath)); 0269 0270 KZip package(packagePath); 0271 QVERIFY(package.open(QIODevice::ReadOnly)); 0272 const KArchiveDirectory *dir = package.directory(); 0273 QVERIFY(dir); // 0274 QVERIFY(dir->entry(QStringLiteral("metadata.json"))); 0275 const KArchiveEntry *contentsEntry = dir->entry(QStringLiteral("contents")); 0276 QVERIFY(contentsEntry); 0277 QVERIFY(contentsEntry->isDirectory()); 0278 const KArchiveDirectory *contents = static_cast<const KArchiveDirectory *>(contentsEntry); 0279 QVERIFY(contents->entry(QStringLiteral("ui"))); 0280 QVERIFY(contents->entry(QStringLiteral("images"))); 0281 0282 m_defaultPackageStructure = new KPackage::PackageStructure(this); 0283 KPackage::Package *p = new KPackage::Package(m_defaultPackageStructure); 0284 qDebug() << "Installing " << packagePath; 0285 // const QString packageRoot = "plasma/plasmoids/"; 0286 // const QString servicePrefix = "plasma-applet-"; 0287 KJob *job = p->install(packagePath, m_packageRoot); 0288 // clang-format off 0289 connect(job, SIGNAL(finished(KJob*)), SLOT(packageInstalled(KJob*))); 0290 QSignalSpy spy(job, SIGNAL(finished(KJob*))); 0291 // clang-format on 0292 QVERIFY(spy.wait(1000)); 0293 0294 // is the package instance usable (ie proper path) after the install job has been completed? 0295 QCOMPARE(p->path(), QString(QDir(m_packageRoot % "/plasmoid_to_package").canonicalPath() + QLatin1Char('/'))); 0296 cleanupPackage(QStringLiteral("plasmoid_to_package")); 0297 0298 // QVERIFY(p->isValid()); 0299 delete p; 0300 } 0301 0302 void PlasmoidPackageTest::noCrashOnAsyncInstall() 0303 { 0304 createTestPackage(QStringLiteral("plasmoid_to_package"), QStringLiteral("1.1")); 0305 const QString packagePath = m_packageRoot + '/' + "testpackage.plasmoid"; 0306 0307 KZip creator(packagePath); 0308 QVERIFY(creator.open(QIODevice::WriteOnly)); 0309 creator.addLocalDirectory(m_packageRoot + '/' + "plasmoid_to_package", QStringLiteral(".")); 0310 creator.close(); 0311 QDir rootDir(m_packageRoot + "/plasmoid_to_package"); 0312 rootDir.removeRecursively(); 0313 0314 KJob *job; 0315 // scope the package so it will get deleted before the install operation finishes 0316 // package is explicitlyshared internally and designed to be used on the stack 0317 // see #370718 0318 { 0319 KPackage::Package package(new KPackage::PackageStructure(this)); 0320 job = package.install(packagePath, m_packageRoot); 0321 } 0322 // clang-format off 0323 connect(job, SIGNAL(finished(KJob*)), SLOT(packageInstalled(KJob*))); 0324 QSignalSpy spy(job, SIGNAL(finished(KJob*))); 0325 // clang-format on 0326 QVERIFY(spy.wait(1000)); 0327 0328 cleanupPackage(QStringLiteral("plasmoid_to_package")); 0329 } 0330 0331 void PlasmoidPackageTest::createAndUpdatePackage() 0332 { 0333 // does the version number parsing work? 0334 QVERIFY(KPackage::isVersionNewer(QStringLiteral("1.1"), QStringLiteral("1.1.1"))); 0335 QVERIFY(!KPackage::isVersionNewer(QStringLiteral("1.1.1"), QStringLiteral("1.1"))); 0336 QVERIFY(KPackage::isVersionNewer(QStringLiteral("1.1.1"), QStringLiteral("1.1.2"))); 0337 QVERIFY(KPackage::isVersionNewer(QStringLiteral("1.1.2"), QStringLiteral("2.1"))); 0338 QVERIFY(KPackage::isVersionNewer(QStringLiteral("0.1.2"), QStringLiteral("2"))); 0339 QVERIFY(!KPackage::isVersionNewer(QStringLiteral("1"), QStringLiteral("0.1.2"))); 0340 0341 qDebug() << " "; 0342 qDebug() << " CreateAndUpdate "; 0343 createTestPackage(QStringLiteral("plasmoid_to_package"), QStringLiteral("1.1")); 0344 const QString packagePath = m_packageRoot + '/' + "testpackage.plasmoid"; 0345 0346 KZip creator(packagePath); 0347 QVERIFY(creator.open(QIODevice::WriteOnly)); 0348 creator.addLocalDirectory(m_packageRoot + '/' + "plasmoid_to_package", QStringLiteral(".")); 0349 creator.close(); 0350 QDir rootDir(m_packageRoot + "/plasmoid_to_package"); 0351 rootDir.removeRecursively(); 0352 0353 QVERIFY(QFile::exists(packagePath)); 0354 0355 KZip package(packagePath); 0356 QVERIFY(package.open(QIODevice::ReadOnly)); 0357 const KArchiveDirectory *dir = package.directory(); 0358 QVERIFY(dir); // 0359 QVERIFY(dir->entry(QStringLiteral("metadata.json"))); 0360 const KArchiveEntry *contentsEntry = dir->entry(QStringLiteral("contents")); 0361 QVERIFY(contentsEntry); 0362 QVERIFY(contentsEntry->isDirectory()); 0363 const KArchiveDirectory *contents = static_cast<const KArchiveDirectory *>(contentsEntry); 0364 QVERIFY(contents->entry(QStringLiteral("ui"))); 0365 QVERIFY(contents->entry(QStringLiteral("images"))); 0366 0367 m_defaultPackageStructure = new KPackage::PackageStructure(this); 0368 KPackage::Package *p = new KPackage::Package(m_defaultPackageStructure); 0369 qDebug() << "Installing " << packagePath; 0370 // const QString packageRoot = "plasma/plasmoids/"; 0371 // const QString servicePrefix = "plasma-applet-"; 0372 0373 // clang-format off 0374 KJob *job = p->update(packagePath, m_packageRoot); 0375 connect(job, SIGNAL(finished(KJob*)), SLOT(packageInstalled(KJob*))); 0376 QSignalSpy spy(job, SIGNAL(finished(KJob*))); 0377 QVERIFY(spy.wait(1000)); 0378 0379 // same version, should fail 0380 job = p->update(packagePath, m_packageRoot); 0381 QSignalSpy spyFail(job, SIGNAL(finished(KJob*))); 0382 QVERIFY(spyFail.wait(1000)); 0383 QVERIFY(job->error() == KPackage::Package::JobError::NewerVersionAlreadyInstalledError); 0384 qDebug()<<job->errorText(); 0385 0386 0387 // create a new package with higher version 0388 createTestPackage(QStringLiteral("plasmoid_to_package"), QStringLiteral("1.2")); 0389 0390 KZip creator2(packagePath); 0391 QVERIFY(creator2.open(QIODevice::WriteOnly)); 0392 creator2.addLocalDirectory(m_packageRoot + '/' + "plasmoid_to_package", QStringLiteral(".")); 0393 creator2.close(); 0394 QDir rootDir2(m_packageRoot + "/plasmoid_to_package"); 0395 rootDir2.removeRecursively(); 0396 0397 0398 KJob *job2 = p->update(packagePath, m_packageRoot); 0399 connect(job2, SIGNAL(finished(KJob*)), SLOT(packageInstalled(KJob*))); 0400 QSignalSpy spy2(job2, SIGNAL(finished(KJob*))); 0401 QVERIFY(spy2.wait(1000)); 0402 // clang-format on 0403 0404 cleanupPackage(QStringLiteral("plasmoid_to_package")); 0405 0406 // QVERIFY(p->isValid()); 0407 delete p; 0408 } 0409 0410 void PlasmoidPackageTest::uncompressPackageWithSubFolder() 0411 { 0412 KPackage::PackageStructure *structure = new KPackage::PackageStructure; 0413 KPackage::Package package(structure); 0414 package.setPath(QFINDTESTDATA("data/customcontent.tar.gz")); 0415 0416 // if metadata is correctly found, servicetypes should be ("SimpleContent", "CustomContent") 0417 QCOMPARE(readKPackageTypes(package.metadata()), QStringList({"SimpleContent", "CustomContent"})); 0418 } 0419 0420 void PlasmoidPackageTest::cleanupPackage(const QString &packageName) 0421 { 0422 KPackage::Package *p = new KPackage::Package(m_defaultPackageStructure); 0423 KJob *jj = p->uninstall(packageName, m_packageRoot); 0424 connect(jj, SIGNAL(finished(KJob *)), SLOT(packageUninstalled(KJob *))); 0425 0426 QSignalSpy spy(jj, &KJob::finished); 0427 QVERIFY(spy.wait(1000)); 0428 } 0429 0430 void PlasmoidPackageTest::packageInstalled(KJob *j) 0431 { 0432 QVERIFY2(j->error() == KJob::NoError, qPrintable(j->errorText())); 0433 } 0434 0435 void PlasmoidPackageTest::packageUninstalled(KJob *j) 0436 { 0437 QVERIFY2(j->error() == KJob::NoError, qPrintable(j->errorText())); 0438 } 0439 0440 QTEST_MAIN(PlasmoidPackageTest)