File indexing completed on 2025-02-02 05:17:19
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * 0003 * * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 ***************************************************************************/ 0006 0007 #include <ApplicationAddonsModel.h> 0008 #include <Category/CategoryModel.h> 0009 #include <ReviewsBackend/ReviewsModel.h> 0010 #include <Transaction/TransactionModel.h> 0011 #include <resources/AbstractBackendUpdater.h> 0012 #include <resources/DiscoverAction.h> 0013 #include <resources/ResourcesModel.h> 0014 #include <resources/ResourcesProxyModel.h> 0015 #include <resources/SourcesModel.h> 0016 0017 #include <QSignalSpy> 0018 #include <QStandardPaths> 0019 #include <QTest> 0020 0021 class FlatpakTest : public QObject 0022 { 0023 Q_OBJECT 0024 public: 0025 AbstractResourcesBackend *backendByName(ResourcesModel *m, const QString &name) 0026 { 0027 const QVector<AbstractResourcesBackend *> backends = m->backends(); 0028 for (AbstractResourcesBackend *backend : backends) { 0029 if (QLatin1String(backend->metaObject()->className()) == name) { 0030 return backend; 0031 } 0032 } 0033 return nullptr; 0034 } 0035 0036 FlatpakTest(QObject *parent = nullptr) 0037 : QObject(parent) 0038 { 0039 QDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + QLatin1String("/discover-flatpak-test")).removeRecursively(); 0040 0041 QStandardPaths::setTestModeEnabled(true); 0042 qputenv("FLATPAK_TEST_MODE", "ON"); 0043 m_model = new ResourcesModel(QStringLiteral("flatpak-backend"), this); 0044 m_appBackend = backendByName(m_model, QStringLiteral("FlatpakBackend")); 0045 } 0046 0047 private Q_SLOTS: 0048 void initTestCase() 0049 { 0050 QVERIFY(m_appBackend); 0051 while (m_appBackend->isFetching()) { 0052 QSignalSpy spy(m_appBackend, &AbstractResourcesBackend::fetchingChanged); 0053 QVERIFY(spy.wait()); 0054 } 0055 } 0056 0057 void testAddSource() 0058 { 0059 auto res = getAllResources(m_appBackend); 0060 QCOMPARE(res.count(), 0); 0061 0062 auto m = SourcesModel::global(); 0063 auto bk = qobject_cast<AbstractSourcesBackend *>(m->index(0, 0).data(SourcesModel::SourcesBackend).value<QObject *>()); 0064 0065 QSignalSpy initializedSpy(m_appBackend, SIGNAL(initialized())); 0066 if (m->rowCount() == 1) { 0067 QSignalSpy spy(m, &SourcesModel::rowsInserted); 0068 qobject_cast<DiscoverAction *>(bk->actions().constFirst().value<QObject *>())->trigger(); 0069 QVERIFY(spy.count() || spy.wait(200000)); 0070 } 0071 QVERIFY(initializedSpy.count() || initializedSpy.wait(200000)); 0072 auto resFlathub = getAllResources(m_appBackend); 0073 QVERIFY(resFlathub.count() > 0); 0074 } 0075 0076 void testListOrigin() 0077 { 0078 AbstractResourcesBackend::Filters f; 0079 f.origin = QStringLiteral("flathub"); 0080 auto resources = getResources(m_appBackend->search(f), true); 0081 QVERIFY(resources.count() > 0); 0082 } 0083 0084 void testInstallApp() 0085 { 0086 AbstractResourcesBackend::Filters f; 0087 f.resourceUrl = QUrl(QStringLiteral("appstream://dosbox.desktop")); 0088 const auto res = getResources(m_appBackend->search(f)); 0089 QCOMPARE(res.count(), 1); 0090 0091 const auto ourResource = res.constFirst(); 0092 QCOMPARE(ourResource->state(), AbstractResource::None); 0093 QCOMPARE(waitTransaction(m_appBackend->installApplication(ourResource)), Transaction::DoneStatus); 0094 QCOMPARE(ourResource->state(), AbstractResource::Installed); 0095 QCOMPARE(waitTransaction(m_appBackend->removeApplication(ourResource)), Transaction::DoneStatus); 0096 QCOMPARE(ourResource->state(), AbstractResource::None); 0097 } 0098 0099 void testFlatpakref() 0100 { 0101 AbstractResourcesBackend::Filters f; 0102 f.resourceUrl = QUrl(QStringLiteral("https://dl.flathub.org/repo/appstream/com.dosbox.DOSBox.flatpakref")); 0103 const auto res = getResources(m_appBackend->search(f)); 0104 QCOMPARE(res.count(), 1); 0105 0106 f.resourceUrl = QUrl(QStringLiteral("appstream://dosbox.desktop")); 0107 const auto res2 = getResources(m_appBackend->search(f)); 0108 QCOMPARE(res2, res); 0109 0110 f.resourceUrl = QUrl(QStringLiteral("appstream://com.dosbox.DOSBox.desktop")); 0111 const auto res3 = getResources(m_appBackend->search(f)); 0112 QCOMPARE(res3, res); 0113 } 0114 0115 /* 0116 void testCancelInstallation() 0117 { 0118 AbstractResourcesBackend::Filters f; 0119 f.resourceUrl = QUrl(QStringLiteral("appstream://com.github.rssguard.desktop")); 0120 const auto res = getResources(m_appBackend->search(f)); 0121 QCOMPARE(res.count(), 1); 0122 0123 const auto resRssguard = res.constFirst(); 0124 QCOMPARE(resRssguard->state(), AbstractResource::None); 0125 auto t = m_appBackend->installApplication(resRssguard); 0126 QSignalSpy spy(t, &Transaction::statusChanged); 0127 QVERIFY(spy.wait()); 0128 QCOMPARE(t->status(), Transaction::CommittingStatus); 0129 t->cancel(); 0130 QVERIFY(spy.wait()); 0131 QCOMPARE(t->status(), Transaction::CancelledStatus); 0132 }*/ 0133 0134 private: 0135 Transaction::Status waitTransaction(Transaction *t) 0136 { 0137 int lastProgress = -1; 0138 connect(t, &Transaction::progressChanged, this, [t, &lastProgress] { 0139 Q_ASSERT(lastProgress <= t->progress()); 0140 lastProgress = t->progress(); 0141 }); 0142 0143 TransactionModel::global()->addTransaction(t); 0144 QSignalSpy spyInstalled(TransactionModel::global(), &TransactionModel::transactionRemoved); 0145 QSignalSpy destructionSpy(t, &QObject::destroyed); 0146 0147 Transaction::Status ret = t->status(); 0148 connect(TransactionModel::global(), &TransactionModel::transactionRemoved, t, [t, &ret](Transaction *trans) { 0149 if (trans == t) { 0150 ret = trans->status(); 0151 } 0152 }); 0153 connect(t, &Transaction::statusChanged, t, [t] { 0154 qDebug() << "status" << t->status(); 0155 }); 0156 while (t && spyInstalled.count() == 0) { 0157 qDebug() << "waiting, currently" << ret << t->progress() << spyInstalled.count() << destructionSpy.count(); 0158 spyInstalled.wait(1000); 0159 } 0160 Q_ASSERT(destructionSpy.count() || destructionSpy.wait()); 0161 return ret; 0162 } 0163 0164 QVector<AbstractResource *> getResources(ResultsStream *stream, bool canBeEmpty = true) 0165 { 0166 Q_ASSERT(stream); 0167 QSignalSpy spyResources(stream, &ResultsStream::destroyed); 0168 QVector<AbstractResource *> resources; 0169 connect(stream, &ResultsStream::resourcesFound, this, [&resources](const QVector<StreamResult> &res) { 0170 for (auto result : res) { 0171 resources += result.resource; 0172 } 0173 }); 0174 Q_ASSERT(spyResources.wait(100000)); 0175 Q_ASSERT(!resources.isEmpty() || canBeEmpty); 0176 return resources; 0177 } 0178 0179 QVector<AbstractResource *> getAllResources(AbstractResourcesBackend *backend) 0180 { 0181 AbstractResourcesBackend::Filters f; 0182 if (CategoryModel::global()->rootCategories().isEmpty()) 0183 CategoryModel::global()->populateCategories(); 0184 f.category = CategoryModel::global()->rootCategories().constFirst(); 0185 return getResources(backend->search(f), true); 0186 } 0187 0188 ResourcesModel *m_model; 0189 AbstractResourcesBackend *m_appBackend; 0190 }; 0191 0192 QTEST_GUILESS_MAIN(FlatpakTest) 0193 0194 #include "FlatpakTest.moc"