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

0001 /*
0002     This file is part of KNewStuff3
0003     SPDX-FileCopyrightText: 2021 Alexander Lohnau <alexander.lohnau@gmx.de>
0004 
0005     SPDX-License-Identifier: LGPL-2.1-or-later
0006 */
0007 
0008 #include <KSharedConfig>
0009 #include <QDir>
0010 #include <QRegularExpression>
0011 #include <QSignalSpy>
0012 #include <QTest>
0013 #include <QtGlobal>
0014 
0015 #include "entry.h"
0016 #include "installation_p.h"
0017 #include "itemsmodel.h"
0018 #include "question.h"
0019 #include "questionmanager.h"
0020 
0021 using namespace KNSCore;
0022 
0023 class InstallationTest : public QObject
0024 {
0025     Q_OBJECT
0026 public:
0027     Installation *installation = nullptr;
0028     const QString dataDir = QStringLiteral(DATA_DIR);
0029 
0030 private Q_SLOTS:
0031     void initTestCase();
0032     void cleanupTestCase();
0033     void testConfigFileReading();
0034     void testInstallCommand();
0035     void testInstallCommandArchive();
0036     void testInstallCommandTopLevelFilesInArchive();
0037     void testUninstallCommand();
0038     void testUninstallCommandDirectory();
0039     void testCopyError();
0040 };
0041 
0042 void InstallationTest::initTestCase()
0043 {
0044     // Just in case a previous test crashed
0045     cleanupTestCase();
0046     qRegisterMetaType<Entry>();
0047     QStandardPaths::setTestModeEnabled(true);
0048     installation = new Installation(this);
0049     KConfigGroup grp = KSharedConfig::openConfig(dataDir + QLatin1String("installationtest.knsrc"))->group(QStringLiteral("KNewStuff"));
0050     QString err;
0051     QVERIFY(installation->readConfig(grp, err));
0052     connect(KNSCore::QuestionManager::instance(), &KNSCore::QuestionManager::askQuestion, this, [](KNSCore::Question *q) {
0053         q->setResponse(KNSCore::Question::YesResponse);
0054     });
0055 }
0056 
0057 void InstallationTest::cleanupTestCase()
0058 {
0059     QFile::remove(QStringLiteral("installed.txt"));
0060     QFile::remove(QStringLiteral("uninstalled.txt"));
0061     const QString dataPath = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("demo/"), QStandardPaths::LocateDirectory);
0062     if (!dataPath.isEmpty()) {
0063         QDir(dataPath).removeRecursively();
0064     }
0065 }
0066 
0067 void InstallationTest::testConfigFileReading()
0068 {
0069     QCOMPARE(installation->uncompressionSetting(), Installation::UncompressIntoSubdirIfArchive);
0070     const QString actualPath = installation->targetInstallationPath();
0071     const QString expectedPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/demo/");
0072     QCOMPARE(actualPath, expectedPath);
0073 }
0074 
0075 void InstallationTest::testInstallCommand()
0076 {
0077     Entry entry;
0078     entry.setUniqueId(QStringLiteral("0"));
0079     entry.setName(QStringLiteral("testInstallCommand"));
0080     entry.setPayload(QUrl::fromLocalFile(QFINDTESTDATA("data/testfile.txt")).toString());
0081     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0082     installation->install(entry);
0083     QVERIFY(spy.wait());
0084     QCOMPARE(entry.status(), KNSCore::Entry::Installed);
0085     QVERIFY(QFileInfo::exists(QStringLiteral("installed.txt")));
0086 }
0087 
0088 void InstallationTest::testUninstallCommand()
0089 {
0090     Entry entry;
0091     entry.setUniqueId(QStringLiteral("0"));
0092     QFile file(QStringLiteral("testFile.txt"));
0093     file.open(QIODevice::WriteOnly);
0094     file.close();
0095     entry.setStatus(KNSCore::Entry::Installed);
0096     entry.setInstalledFiles(QStringList(file.fileName()));
0097     QVERIFY(QFileInfo(file).exists());
0098     QVERIFY(!QFileInfo::exists(QStringLiteral("uninstalled.txt")));
0099 
0100     installation->uninstall(entry);
0101     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0102     QVERIFY(spy.wait());
0103     QCOMPARE(entry.status(), KNSCore::Entry::Deleted);
0104     QVERIFY(!QFileInfo(file).exists());
0105     QVERIFY(QFileInfo::exists(QStringLiteral("uninstalled.txt")));
0106 }
0107 
0108 void InstallationTest::testUninstallCommandDirectory()
0109 {
0110     static const QLatin1String testDir{"testDirectory"};
0111 
0112     // This will be left over from the previous test, so clean it up first
0113     QFile::remove(QStringLiteral("uninstalled.txt"));
0114 
0115     Entry entry;
0116     entry.setUniqueId(QStringLiteral("0"));
0117     QDir().mkdir(testDir);
0118     entry.setStatus(KNSCore::Entry::Installed);
0119     entry.setInstalledFiles(QStringList(testDir));
0120     QVERIFY(QFileInfo::exists(testDir));
0121     QVERIFY(!QFileInfo::exists(QStringLiteral("uninstalled.txt")));
0122 
0123     installation->uninstall(entry);
0124     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0125     QVERIFY(spy.wait());
0126     QCOMPARE(entry.status(), KNSCore::Entry::Deleted);
0127     QVERIFY(!QFileInfo::exists(testDir));
0128     QVERIFY(QFileInfo::exists(QStringLiteral("uninstalled.txt")));
0129 }
0130 
0131 void InstallationTest::testInstallCommandArchive()
0132 {
0133     Entry entry;
0134     entry.setUniqueId(QStringLiteral("0"));
0135     entry.setStatus(KNSCore::Entry::Downloadable);
0136     entry.setPayload(QUrl::fromLocalFile(QFINDTESTDATA("data/archive_dir.tar.gz")).toString());
0137 
0138     installation->install(entry);
0139     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0140     QVERIFY(spy.wait());
0141 
0142     QCOMPARE(entry.installedFiles().count(), 1);
0143     const QString file = entry.installedFiles().constFirst();
0144     const QFileInfo fileInfo(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("demo/data"), QStandardPaths::LocateDirectory));
0145     QCOMPARE(file, fileInfo.absoluteFilePath() + QLatin1String("/*"));
0146     QVERIFY(fileInfo.exists());
0147     QVERIFY(fileInfo.isDir());
0148 
0149     // Check if the files that are in the archive exist
0150     const QStringList files = QDir(fileInfo.absoluteFilePath()).entryList(QDir::Filter::Files | QDir::Filter::NoDotAndDotDot);
0151     QCOMPARE(files, QStringList({QStringLiteral("test1.txt"), QStringLiteral("test2.txt")}));
0152 }
0153 
0154 void InstallationTest::testInstallCommandTopLevelFilesInArchive()
0155 {
0156     Entry entry;
0157     entry.setUniqueId(QStringLiteral("0"));
0158     entry.setStatus(KNSCore::Entry::Downloadable);
0159     entry.setPayload(QUrl::fromLocalFile(QFINDTESTDATA("data/archive_toplevel_files.tar.gz")).toString());
0160 
0161     installation->install(entry);
0162     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0163     QVERIFY(spy.wait());
0164 
0165     QCOMPARE(entry.installedFiles().count(), 1);
0166     const QString file = entry.installedFiles().constFirst();
0167     QVERIFY(file.endsWith(QLatin1String("/*")));
0168 
0169     // The file is given a random name, so we can't easily check that
0170     const QFileInfo fileOnDisk(file.left(file.size() - 2));
0171     QVERIFY(fileOnDisk.exists());
0172     QVERIFY(fileOnDisk.isDir());
0173     // The by checking the parent dir we can check if it is properly in a subdir uncompressed
0174     QCOMPARE(fileOnDisk.absoluteDir().path(),
0175              QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("demo"), QStandardPaths::LocateDirectory));
0176     // Check if the files that are in the archive exist
0177     const QStringList files = QDir(fileOnDisk.absoluteFilePath()).entryList(QDir::Filter::Files | QDir::Filter::NoDotAndDotDot);
0178     QCOMPARE(files, QStringList({QStringLiteral("test1.txt"), QStringLiteral("test2.txt")}));
0179 }
0180 
0181 void InstallationTest::testCopyError()
0182 {
0183     Entry entry;
0184     entry.setUniqueId(QStringLiteral("0"));
0185     entry.setPayload(QUrl::fromLocalFile(QStringLiteral("data/does_not_exist.txt")).toString());
0186     QSignalSpy spy(installation, &Installation::signalEntryChanged);
0187     QSignalSpy errorSpy(installation, &Installation::signalInstallationFailed);
0188     QTest::ignoreMessage(QtWarningMsg, QRegularExpression(QStringLiteral("Download of .* failed, error: Could not open data/does_not_exist.txt for reading")));
0189     installation->install(entry);
0190     QVERIFY(errorSpy.wait());
0191     QCOMPARE(spy.count(), 0);
0192     QCOMPARE(int(entry.status()), int(KNSCore::Entry::Invalid));
0193 }
0194 
0195 QTEST_MAIN(InstallationTest)
0196 
0197 #include "installationtest.moc"