diff --git a/autotests/knewstuffentrytest.cpp b/autotests/knewstuffentrytest.cpp
--- a/autotests/knewstuffentrytest.cpp
+++ b/autotests/knewstuffentrytest.cpp
@@ -44,6 +44,7 @@
"https://testpreview"
"http://testpayload"
"" "" "installed" "" ""
+"ghns_exclude=1"
"";
const QString name = QStringLiteral("Name");
diff --git a/src/attica/atticaprovider.cpp b/src/attica/atticaprovider.cpp
--- a/src/attica/atticaprovider.cpp
+++ b/src/attica/atticaprovider.cpp
@@ -18,6 +18,7 @@
#include "atticaprovider_p.h"
#include "question.h"
+#include "tagsfilterchecker.h"
#include
#include
@@ -269,9 +270,23 @@
Content::List contents = listJob->itemList();
EntryInternal::List entries;
+ TagsFilterChecker checker(mCurrentRequest.tagFilter);
+ TagsFilterChecker downloadschecker(mCurrentRequest.downloadTagFilter);
Q_FOREACH (const Content &content, contents) {
- mCachedContent.insert(content.id(), content);
- entries.append(entryFromAtticaContent(content));
+ bool filterAcceptsDownloads = content.downloads() == 0 ? true : false;
+ foreach(const Attica::DownloadDescription & dli, content.downloadUrlDescriptions()) {
+ filterAcceptsDownloads = downloadschecker.filterAccepts(dli.tags());
+ if(filterAcceptsDownloads) {
+ break;
+ }
+ }
+ if(filterAcceptsDownloads && checker.filterAccepts(content.tags())) {
+ mCachedContent.insert(content.id(), content);
+ entries.append(entryFromAtticaContent(content));
+ }
+ else {
+ qCDebug(KNEWSTUFFCORE) << "Filter has excluded" << content.name() << "on entry filter" << mCurrentRequest.tagFilter << "and download filter" << mCurrentRequest.downloadTagFilter;
+ }
}
qCDebug(KNEWSTUFFCORE) << "loaded: " << mCurrentRequest.hashForRequest() << " count: " << entries.size();
@@ -481,6 +496,7 @@
entry.setSummary(content.description());
entry.setShortSummary(content.summary());
entry.setChangelog(content.changelog());
+ entry.setTags(content.tags());
entry.clearDownloadLinkInformation();
QList descs = content.downloadUrlDescriptions();
@@ -493,6 +509,7 @@
info.id = desc.id();
info.size = desc.size();
info.isDownloadtypeLink = desc.type() == Attica::DownloadDescription::LinkDownload;
+ info.tags = desc.tags();
entry.appendDownloadLinkInformation(info);
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -9,6 +9,7 @@
itemsmodel.cpp
provider.cpp
security.cpp
+ tagsfilterchecker.cpp
xmlloader.cpp
# A system by which queries can be passed to the user, and responses
diff --git a/src/core/engine.h b/src/core/engine.h
--- a/src/core/engine.h
+++ b/src/core/engine.h
@@ -179,6 +179,81 @@
void requestMoreData();
void requestData(int page, int pageSize);
+ /**
+ * Set a filter for results, which filters out all entries which do not match
+ * the filter, as applied to the tags for the entry. This filters only on the
+ * tags specified for the entry itself. To filter the downloadlinks, use
+ * setDownloadTagFilter(QStringList).
+ *
+ * @note The default filter if one is not set from your knsrc file will filter
+ * out entries marked as ghns_exclude=1. To retain this when setting a custom
+ * filter, add "ghns_exclude!=1" as one of the filters.
+ *
+ * @note Some tags provided by OCS do not supply a value (and are simply passsed
+ * as a key). These will be interpreted as having the value 1 for filtering
+ * purposes. An example of this might be ghns_exclude, which in reality will
+ * generally be passed through ocs as "ghns_exclude" rather than "ghns_exclude=1"
+ *
+ * == Examples of use ==
+ * Value for tag "tagname" must be exactly "tagdata":
+ * tagname==tagdata
+ *
+ * Value for tag "tagname" must be different from "tagdata":
+ * tagname!=tagdata
+ *
+ * == KNSRC entry ==
+ * A tag filter line in a .knsrc file, which is a comma semarated list of
+ * tag/value pairs, might look like:
+ *
+ * TagFilter=ghns_exclude!=1,data##mimetype==application/cbr+zip,data##mimetype==application/cbr+rar
+ * which would honour the exclusion and filter out anything that does not
+ * include a comic book archive in either zip or rar format in one or more
+ * of the download items.
+ * Notice in particular that there are two data##mimetype entries. Use this
+ * for when a tag may have multiple values.
+ *
+ * TagFilter=application##architecture==x86_64
+ * which would not honour the exclusion, and would filter out all entries
+ * which do not mark themselves as having a 64bit application binary in at
+ * least one download item.
+ *
+ * The value does not current suppport wildcards. The list should be considered
+ * a binary AND operation (that is, all filter entries must match for the data
+ * entry to be included in the return data)
+ *
+ * @param filter The filter in the form of a list of strings
+ * @see setDownloadTagFilter(QStringList)
+ */
+ void setTagFilter(QStringList filter);
+ /**
+ * Gets the current tag filter list
+ * @see setTagFilter(QStringList)
+ */
+ QStringList tagFilter() const;
+ /**
+ * Sets a filter to be applied to the downloads for an entry. The logic is the
+ * same as used in setTagFilter(QStringList), but vitally, only one downloadlink
+ * is required to match the filter for the list to be valid. If you do not wish
+ * to show the others in your client, you must hide them yourself.
+ *
+ * For an entry to be accepted when a download tag filter is set, it must also
+ * be accepted by the entry filter (so, for example, while a list of downloads
+ * might be accepted, if the entry has ghns_exclude set, and the default entry
+ * filter is set, the entry will still be filtered out).
+ *
+ * In your knsrc file, set DownloadTagFilter to the filter you wish to apply,
+ * using the same logic as described for the entry tagfilter.
+ *
+ * @param filter The filter in the form of a list of strings
+ * @see setTagFilter(QStringList)
+ */
+ void setDownloadTagFilter(QStringList filter);
+ /**
+ * Gets the current downloadlink tag filter list
+ * @see setDownloadTagFilter(QStringList)
+ */
+ QStringList downloadTagFilter() const;
+
/**
* Request for packages that are installed and need update
*
diff --git a/src/core/engine.cpp b/src/core/engine.cpp
--- a/src/core/engine.cpp
+++ b/src/core/engine.cpp
@@ -61,6 +61,8 @@
public:
QList categoriesMetadata;
Attica::ProviderManager *m_atticaProviderManager = nullptr;
+ QStringList tagFilter;
+ QStringList downloadTagFilter;
};
Engine::Engine(QObject *parent)
@@ -126,6 +128,17 @@
qCDebug(KNEWSTUFFCORE) << "Categories: " << m_categories;
m_providerFileUrl = group.readEntry("ProvidersUrl", QString());
+ d->tagFilter = group.readEntry("TagFilter").split(QStringLiteral(","));
+ if(d->tagFilter.length() == 1 && d->tagFilter.at(0).isEmpty()) {
+ d->tagFilter[0] = QStringLiteral("ghns_exclude!=1");
+ }
+ m_currentRequest.tagFilter = d->tagFilter;
+ d->downloadTagFilter = group.readEntry("DownloadTagFilter").split(QStringLiteral(","));
+ if(d->downloadTagFilter.length() == 1 && d->downloadTagFilter.at(0).isEmpty()) {
+ d->downloadTagFilter.clear();
+ }
+ m_currentRequest.downloadTagFilter = d->downloadTagFilter;
+
const QString configFileName = QFileInfo(QDir::isAbsolutePath(configfile) ? configfile : QStandardPaths::locate(QStandardPaths::GenericConfigLocation, configfile)).baseName();
// let installation read install specific config
if (!m_installation->readConfig(group)) {
@@ -304,6 +317,8 @@
{
emit signalResetView();
m_currentPage = -1;
+ m_currentRequest.tagFilter = tagFilter();
+ m_currentRequest.downloadTagFilter = downloadTagFilter();
m_currentRequest.pageSize = m_pageSize;
m_currentRequest.page = 0;
m_numDataJobs = 0;
@@ -374,6 +389,8 @@
m_searchTimer->stop();
m_currentRequest = KNSCore::Provider::SearchRequest(KNSCore::Provider::Newest, KNSCore::Provider::ExactEntryId, id);
m_currentRequest.pageSize = m_pageSize;
+ m_currentRequest.tagFilter = tagFilter();
+ m_currentRequest.downloadTagFilter = downloadTagFilter();
EntryInternal::List cache = m_cache->requestFromCache(m_currentRequest);
if (!cache.isEmpty()) {
@@ -395,6 +412,28 @@
}
}
+void Engine::setTagFilter(QStringList filter)
+{
+ d->tagFilter = filter;
+ m_currentRequest.tagFilter = filter;
+}
+
+QStringList Engine::tagFilter() const
+{
+ return d->tagFilter;
+}
+
+void Engine::setDownloadTagFilter(QStringList filter)
+{
+ d->downloadTagFilter = filter;
+ m_currentRequest.downloadTagFilter = filter;
+}
+
+QStringList Engine::downloadTagFilter() const
+{
+ return d->downloadTagFilter;
+}
+
void Engine::slotSearchTimerExpired()
{
reloadEntries();
diff --git a/src/core/entryinternal.h b/src/core/entryinternal.h
--- a/src/core/entryinternal.h
+++ b/src/core/entryinternal.h
@@ -89,6 +89,7 @@
int id;
bool isDownloadtypeLink;
quint64 size = 0;
+ QStringList tags;
};
/**
@@ -440,6 +441,16 @@
*/
void setDonationLink(const QString &link);
+ /**
+ * The set of tags assigned specifically to this content item. This does not include
+ * tags for the download links. To get those, you must concatenate the lists yourself.
+ * @see downloadLinkInformationList()
+ * @see DownloadLinkInformation
+ * @see Engine::setTagFilter(QStringList)
+ */
+ QStringList tags() const;
+ void setTags(const QStringList &tags);
+
/**
The id of the provider this entry belongs to
*/
diff --git a/src/core/entryinternal.cpp b/src/core/entryinternal.cpp
--- a/src/core/entryinternal.cpp
+++ b/src/core/entryinternal.cpp
@@ -79,6 +79,7 @@
QString mProviderId;
QStringList mUnInstalledFiles;
QString mDonationLink;
+ QStringList mTags;
QString mChecksum;
QString mSignature;
@@ -156,6 +157,16 @@
d->mProviderId = id;
}
+QStringList KNSCore::EntryInternal::tags() const
+{
+ return d->mTags;
+}
+
+void KNSCore::EntryInternal::setTags(const QStringList& tags)
+{
+ d->mTags = tags;
+}
+
QString EntryInternal::category() const
{
return d->mCategory;
@@ -481,7 +492,7 @@
bool KNSCore::EntryInternal::setEntryXML(QXmlStreamReader& reader)
{
if (reader.name() != QLatin1String("stuff")) {
- qWarning() << "Parsing Entry from invalid XML";
+ qWarning() << "Parsing Entry from invalid XML. Reader tag name was expected to be \"stuff\", but was found as:" << reader.name();
return false;
}
@@ -540,6 +551,8 @@
d->mInstalledFiles.append(reader.readElementText(QXmlStreamReader::SkipChildElements));
} else if (reader.name() == QLatin1String("id")) {
d->mUniqueId = reader.readElementText(QXmlStreamReader::SkipChildElements);
+ } else if (reader.name() == QLatin1String("tags")) {
+ d->mTags = reader.readElementText(QXmlStreamReader::SkipChildElements).split(QChar(','));
} else if (reader.name() == QLatin1String("status")) {
const auto statusText = readText(&reader);
if (statusText == QLatin1String("installed")) {
@@ -551,7 +564,7 @@
if (reader.tokenType() == QXmlStreamReader::Characters)
readNextSkipComments(&reader);
}
- Q_ASSERT(reader.tokenType() == QXmlStreamReader::EndElement);
+ Q_ASSERT_X(reader.tokenType() == QXmlStreamReader::EndElement, Q_FUNC_INFO, QString("token name was %1 and the type was %2").arg(reader.name()).arg(reader.tokenString()).toLocal8Bit().data());
}
// Validation
@@ -633,6 +646,8 @@
d->mInstalledFiles.append(e.text());
} else if (e.tagName() == QLatin1String("id")) {
d->mUniqueId = e.text();
+ } else if (e.tagName() == QLatin1String("tags")) {
+ d->mTags = e.text().split(QChar(','));
} else if (e.tagName() == QLatin1String("status")) {
QString statusText = e.text();
if (statusText == QLatin1String("installed")) {
@@ -724,6 +739,7 @@
e = addElement(doc, el, QStringLiteral("preview"), d->mPreviewUrl[PreviewSmall1]);
e = addElement(doc, el, QStringLiteral("previewBig"), d->mPreviewUrl[PreviewBig1]);
e = addElement(doc, el, QStringLiteral("payload"), d->mPayload);
+ e = addElement(doc, el, QStringLiteral("tags"), d->mTags.join(QChar(',')));
if (d->mStatus == KNS3::Entry::Installed) {
(void)addElement(doc, el, QStringLiteral("status"), QStringLiteral("installed"));
diff --git a/src/core/provider.h b/src/core/provider.h
--- a/src/core/provider.h
+++ b/src/core/provider.h
@@ -72,13 +72,15 @@
struct SearchRequest {
SortMode sortMode;
Filter filter;
+ QStringList tagFilter;
+ QStringList downloadTagFilter;
QString searchTerm;
QStringList categories;
int page;
int pageSize;
- SearchRequest(SortMode sortMode_ = Newest, Filter filter_ = None, const QString &searchTerm_ = QString(), const QStringList &categories_ = QStringList(), int page_ = -1, int pageSize_ = 20)
- : sortMode(sortMode_), filter(filter_), searchTerm(searchTerm_), categories(categories_), page(page_), pageSize(pageSize_)
+ SearchRequest(SortMode sortMode_ = Newest, Filter filter_ = None, const QString &searchTerm_ = QString(), const QStringList &categories_ = QStringList(), int page_ = -1, int pageSize_ = 20, const QStringList &tagFilter_ = QStringList(), const QStringList &downloadTagFilter_ = QStringList())
+ : sortMode(sortMode_), filter(filter_), tagFilter(tagFilter_), downloadTagFilter(downloadTagFilter_), searchTerm(searchTerm_), categories(categories_), page(page_), pageSize(pageSize_)
{}
QString hashForRequest() const;
diff --git a/src/core/tagsfilterchecker.h b/src/core/tagsfilterchecker.h
new file mode 100644
--- /dev/null
+++ b/src/core/tagsfilterchecker.h
@@ -0,0 +1,79 @@
+/*
+ Copyright (c) 2018 Dan Leinir Turthra Jensen
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see .
+*/
+
+#ifndef KNSCORE_TAGSFILTERCHECKER_H
+#define KNSCORE_TAGSFILTERCHECKER_H
+
+#include
+
+namespace KNSCore {
+
+/**
+ * @brief Apply simple filtering logic to a list of tags
+ *
+ * == Examples of specifying tag filters ==
+ * Value for tag "tagname" must be exactly "tagdata":
+ * tagname==tagdata
+ *
+ * Value for tag "tagname" must be different from "tagdata":
+ * tagname!=tagdata
+ *
+ * == Tag filter list ==
+ * A tag filter list is a string list of filters as shown above, and a combination
+ * of which might look like:
+ *
+ * - ghns_exclude!=1
+ * - data##mimetype==application/cbr+zip
+ * - data##mimetype==application/cbr+rar
+ *
+ * which would filter out anything which has ghns_exclude set to 1, and
+ * anything where the value of data##mimetype does not equal either
+ * "application/cbr+zip" or "application/cbr+rar".
+ * Notice in particular the two data##mimetype entries. Use this
+ * for when a tag may have multiple values.
+ *
+ * The value does not current suppport wildcards. The list should be considered
+ * a binary AND operation (that is, all filter entries must match for the data
+ * entry to be included in the return data)
+ */
+class TagsFilterChecker {
+public:
+ /**
+ * Constructs an instance of the tags filter checker, prepopulated
+ * with the list of tag filters in the tagFilter parameter.
+ *
+ * @param tagFilter The list of tag filters
+ */
+ TagsFilterChecker(const QStringList& tagFilter);
+ ~TagsFilterChecker();
+
+ /**
+ * Check whether the filter list accepts the passed list of tags
+ *
+ * @param tags A list of tags in the form of key=value strings
+ * @return True if the filter accepts the list, false if not
+ */
+ bool filterAccepts(const QStringList& tags);
+
+private:
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif//KNSCORE_TAGSFILTERCHECKER_H
diff --git a/src/core/tagsfilterchecker.cpp b/src/core/tagsfilterchecker.cpp
new file mode 100644
--- /dev/null
+++ b/src/core/tagsfilterchecker.cpp
@@ -0,0 +1,179 @@
+/*
+ Copyright (c) 2018 Dan Leinir Turthra Jensen
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see .
+*/
+
+#include "tagsfilterchecker.h"
+
+#include
+
+#include
+
+namespace KNSCore
+{
+
+class TagsFilterChecker::Private
+{
+public:
+ Private() {}
+ ~Private()
+ {
+ qDeleteAll(validators.values());
+ }
+ class Validator;
+ // If people start using a LOT of validators (>20ish), we can always change it, but
+ // for now it seems reasonable that QMap is better than QHash here...
+ QMap validators;
+
+ class Validator
+ {
+ public:
+ Validator(const QString& tag, const QString value) {
+ m_tag = tag;
+ m_acceptedValues << value;
+ }
+ virtual ~Validator() {};
+ virtual bool filterAccepts(const QString& tag, const QString& value) = 0;
+ protected:
+ friend class TagsFilterChecker::Private;
+ QString m_tag;
+ QStringList m_acceptedValues;
+ };
+
+ // Will only accept entries which have one of the accepted values set for the tag key
+ class EqualityValidator : public Validator
+ {
+ public:
+ EqualityValidator(const QString& tag, const QString value)
+ : Validator(tag, value)
+ {}
+ ~EqualityValidator() override {}
+ bool filterAccepts(const QString& tag, const QString& value) override
+ {
+ bool result = true;
+ if(tag == m_tag && !m_acceptedValues.contains(value)) {
+ result = false;
+ }
+ return result;
+ }
+ };
+
+ // Will only accept entries which have none of the values set for the tag key
+ class InequalityValidator : public Validator
+ {
+ public:
+ InequalityValidator(const QString& tag, const QString value)
+ : Validator(tag, value)
+ {}
+ ~InequalityValidator() override {}
+ bool filterAccepts(const QString& tag, const QString& value) override
+ {
+ bool result = true;
+ if(tag == m_tag && m_acceptedValues.contains(value)) {
+ result = false;
+ }
+ return result;
+ }
+ };
+
+ void addValidator(const QString& filter)
+ {
+ int pos = 0;
+ if((pos = filter.indexOf(QStringLiteral("=="))) > -1)
+ {
+ QString tag = filter.left(pos);
+ QString value = filter.mid(tag.length() + 2);
+ Validator* val = validators.value(tag, nullptr);
+ if(val)
+ {
+ val->m_acceptedValues << value;
+ }
+ else
+ {
+ val = new EqualityValidator(tag, value);
+ validators[tag] = val;
+ }
+ qCDebug(KNEWSTUFFCORE) << "Created EqualityValidator for tag" << tag << "with value" << value;
+ }
+ else if((pos = filter.indexOf(QStringLiteral("!="))) > -1)
+ {
+ QString tag = filter.left(pos);
+ QString value = filter.mid(tag.length() + 2);
+ Validator* val = validators.value(tag, nullptr);
+ if(val)
+ {
+ val->m_acceptedValues << value;
+ }
+ else
+ {
+ val = new InequalityValidator(tag, value);
+ validators[tag] = val;
+ }
+ qCDebug(KNEWSTUFFCORE) << "Created InequalityValidator for tag" << tag << "with value" << value;
+ }
+ else
+ {
+ qCDebug(KNEWSTUFFCORE) << "Critical error attempting to create tag filter validators. The filter is defined as" << filter << "which is not in the accepted formats key==value or key!=value";
+ }
+ }
+};
+
+TagsFilterChecker::TagsFilterChecker(const QStringList& tagFilter)
+ : d(new TagsFilterChecker::Private)
+{
+ for(const QString& filter : tagFilter) {
+ d->addValidator(filter);
+ }
+}
+
+TagsFilterChecker::~TagsFilterChecker()
+{
+ delete d;
+}
+
+bool TagsFilterChecker::filterAccepts(const QStringList& tags)
+{
+ // if any tag in the content matches any of the tag filters, skip this entry
+ qCDebug(KNEWSTUFFCORE) << "Checking tags list" << tags << "against validators with keys" << d->validators.keys();
+ for(const QString &tag : tags) {
+ if(tag.length() == 0) {
+ // This happens when you do a split on an empty string (not an empty list, a list with one empty element... because reasons).
+ // Also handy for other things, i guess, though, so let's just catch it here.
+ continue;
+ }
+ QStringList current = tag.split(QStringLiteral("="));
+ if(current.length() > 2) {
+ qCDebug(KNEWSTUFFCORE) << "Critical error attempting to filter tags. Entry has tag defined as" << tag << "which is not in the format \"key=value\" or \"key\".";
+ return false;
+ }
+ else if(current.length() == 1) {
+ // If the tag is defined simply as a key, we give it the value "1", just to make our filtering work simpler
+ current << QStringLiteral("1");
+ }
+ QMap::const_iterator i = d->validators.constBegin();
+ while(i != d->validators.constEnd()) {
+ if(!i.value()->filterAccepts(current.at(0), current.at(1))) {
+ return false;
+ }
+ ++i;
+ }
+ }
+ // If we have arrived here, nothing has filtered the entry
+ // out (by being either incorrectly tagged or a filter rejecting
+ // it), and consequently it is an acceptable entry.
+ return true;
+}
+
+}
diff --git a/src/staticxml/staticxmlprovider.cpp b/src/staticxml/staticxmlprovider.cpp
--- a/src/staticxml/staticxmlprovider.cpp
+++ b/src/staticxml/staticxmlprovider.cpp
@@ -27,6 +27,7 @@
#include
#include
+#include
namespace KNSCore
@@ -200,6 +201,8 @@
const Provider::Filter filter = loader->property("filter").value();
const QString searchTerm = loader->property("searchTerm").toString();
+ TagsFilterChecker checker(mCurrentRequest.tagFilter);
+ TagsFilterChecker downloadschecker(mCurrentRequest.downloadTagFilter);
element = doc.documentElement();
QDomElement n;
for (n = element.firstChildElement(); !n.isNull(); n = n.nextSiblingElement()) {
@@ -225,28 +228,41 @@
}
cacheEntry = entry;
}
- mCachedEntries.append(entry);
-
- if (searchIncludesEntry(entry)) {
- switch(filter) {
- case Installed:
- //This is dealth with in loadEntries separately
- Q_UNREACHABLE();
- case Updates:
- if (entry.status() == KNS3::Entry::Updateable) {
- entries << entry;
- }
- break;
- case ExactEntryId:
- if (entry.uniqueId() == searchTerm) {
+
+ bool filterAcceptsDownloads = entry.downloadCount() == 0 ? true : false;
+ foreach(const KNSCore::EntryInternal::DownloadLinkInformation& dli, entry.downloadLinkInformationList()) {
+ filterAcceptsDownloads = downloadschecker.filterAccepts(dli.tags);
+ if(filterAcceptsDownloads) {
+ break;
+ }
+ }
+ if(filterAcceptsDownloads && checker.filterAccepts(entry.tags())) {
+ mCachedEntries.append(entry);
+
+ if (searchIncludesEntry(entry)) {
+ switch(filter) {
+ case Installed:
+ //This is dealth with in loadEntries separately
+ Q_UNREACHABLE();
+ case Updates:
+ if (entry.status() == KNS3::Entry::Updateable) {
+ entries << entry;
+ }
+ break;
+ case ExactEntryId:
+ if (entry.uniqueId() == searchTerm) {
+ entries << entry;
+ }
+ break;
+ case None:
entries << entry;
- }
- break;
- case None:
- entries << entry;
- break;
+ break;
+ }
}
}
+ else {
+ qCDebug(KNEWSTUFFCORE) << "Filter has excluded" << entry.name() << "on entry filter" << mCurrentRequest.tagFilter << "and download filter" << mCurrentRequest.downloadTagFilter;
+ }
}
emit loadingFinished(mCurrentRequest, entries);
}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,25 +1,27 @@
include(ECMMarkAsTest)
-find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test Widgets) # Widgets for KMoreTools
+find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test Widgets Gui Quick) # Widgets for KMoreTools and Qick for the interactive KNS test
+
+configure_file(khotnewstuff_test.knsrc.in khotnewstuff_test.knsrc @ONLY)
macro(knewstuff_executable_tests)
foreach(_testname ${ARGN})
- add_executable(${_testname} ${_testname}.cpp ../src/knewstuff_debug.cpp)
- target_link_libraries(${_testname} KF5::NewStuffCore KF5::NewStuff KF5::I18n Qt5::Xml Qt5::Test)
+ add_executable(${_testname} ${_testname}.cpp ../src/knewstuff_debug.cpp ../src/core/knewstuffcore_debug.cpp ../src/core/tagsfilterchecker.cpp ../src/staticxml/staticxmlprovider.cpp)
+ target_link_libraries(${_testname} KF5::NewStuffCore KF5::NewStuff KF5::I18n Qt5::Xml Qt5::Test Qt5::Quick Qt5::Gui)
target_compile_definitions(${_testname} PRIVATE
- KNSSRCDIR="\\"${CMAKE_CURRENT_SOURCE_DIR}/\\""
- KNSBUILDDIR="\\"${CMAKE_CURRENT_BINARY_DIR}\\"")
+ KNSSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}/"
+ KNSBUILDDIR="${CMAKE_CURRENT_BINARY_DIR}")
endforeach()
endmacro()
knewstuff_executable_tests(
khotnewstuff
khotnewstuff_upload
+ khotnewstuff_test
)
# FIXME: port to new API
#knewstuff_executable_tests(
-# knewstuff2_test
# knewstuff2_download
# knewstuff2_standard
# knewstuff2_cache
diff --git a/tests/khotnewstuff_test-ui/main.qml b/tests/khotnewstuff_test-ui/main.qml
new file mode 100644
--- /dev/null
+++ b/tests/khotnewstuff_test-ui/main.qml
@@ -0,0 +1,67 @@
+import QtQuick 2.7
+import org.kde.kirigami 2.4 as Kirigami
+
+Kirigami.ApplicationWindow {
+ id: root;
+
+ globalDrawer: Kirigami.GlobalDrawer {
+ title: "KNewStuff Test"
+ titleIcon: "applications-development"
+ drawerOpen: true;
+ modal: false;
+
+ actions: [
+ Kirigami.Action {
+ text: "Run Engine test"
+ onTriggered: testObject.engineTest();
+ iconName: "run-build"
+ },
+ Kirigami.Action {
+ text: "Test entry download as well"
+ onTriggered: testObject.testAll = !testObject.testAll
+ iconName: typeof(testObject) !== "undefined" ? (testObject.testAll ? "checkmark" : "") : ""
+ },
+ Kirigami.Action {},
+ Kirigami.Action {
+ text: "Run Entry test"
+ onTriggered: testObject.entryTest();
+ iconName: "run-build"
+ },
+ Kirigami.Action {
+ text: "Run Provider test"
+ onTriggered: testObject.providerTest();
+ iconName: "run-build"
+ }
+ ]
+ }
+ contextDrawer: Kirigami.ContextDrawer {
+ id: contextDrawer
+ }
+
+ pageStack.initialPage: mainPageComponent
+
+ Component {
+ id: mainPageComponent
+ Kirigami.ScrollablePage {
+ title: "Welcome"
+ ListView {
+ id: messageView;
+ model: testObject.messages();
+ onCountChanged: {
+ messageView.currentIndex = messageView.count - 1;
+ }
+ delegate: Kirigami.BasicListItem {
+ id: listItem
+
+ reserveSpaceForIcon: true
+ label: model.display
+ icon: model.whatsThis
+
+ Accessible.role: Accessible.MenuItem
+ onClicked: {}
+ highlighted: focus && ListView.isCurrentItem
+ }
+ }
+ }
+ }
+}
diff --git a/tests/knewstuff2_test.h b/tests/khotnewstuff_test.h
rename from tests/knewstuff2_test.h
rename to tests/khotnewstuff_test.h
--- a/tests/knewstuff2_test.h
+++ b/tests/khotnewstuff_test.h
@@ -19,39 +19,46 @@
#ifndef KNEWSTUFF2_TEST_TEST_H
#define KNEWSTUFF2_TEST_TEST_H
-#include
-#include
+#include
+#include
#include
+#include
-namespace KNS
+namespace KNSCore
{
-class CoreEngine;
+class Engine;
}
class KNewStuff2Test : public QObject
{
Q_OBJECT
+ Q_PROPERTY(bool testAll READ testAll WRITE setTestAll NOTIFY testAllChanged)
public:
- KNewStuff2Test();
+ KNewStuff2Test(const QString& configFile);
+
void setTestAll(bool testall);
- void entryTest();
- void providerTest();
- void engineTest();
+ bool testAll() const;
+ Q_SIGNAL void testAllChanged();
+
+ Q_INVOKABLE void entryTest();
+ Q_INVOKABLE void providerTest();
+ Q_INVOKABLE void engineTest();
+
+ Q_INVOKABLE QObject* messages();
+ void addMessage(const QString& message, const QString& iconName = QStringLiteral());
+
public Q_SLOTS:
- void slotProviderLoaded(KNS::Provider *provider);
- void slotProvidersFailed();
- void slotEntryLoaded(KNS::Entry *entry, const KNS::Feed *feed, const KNS::Provider *provider);
- void slotEntriesFailed();
- void slotEntriesFinished();
- void slotPayloadLoaded(QUrl payload);
- void slotPayloadFailed();
+ void slotProvidersLoaded();
+ void slotEngineError(const QString& error);
+ void slotEntriesLoaded(const KNSCore::EntryInternal::List &entries);
void slotInstallationFinished();
- void slotInstallationFailed();
+
private:
- void quitTest();
- KNS::CoreEngine *m_engine;
+ KNSCore::Engine *m_engine;
bool m_testall;
+ QString m_configFile;
+ QStandardItemModel* m_messages;
};
#endif
diff --git a/tests/khotnewstuff_test.cpp b/tests/khotnewstuff_test.cpp
new file mode 100644
--- /dev/null
+++ b/tests/khotnewstuff_test.cpp
@@ -0,0 +1,245 @@
+/*
+ This file is part of KNewStuff2.
+ Copyright (c) 2007 Josef Spillner
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see .
+*/
+
+#include "khotnewstuff_test.h"
+
+#include
+#include
+#include
+#include "../src/staticxml/staticxmlprovider_p.h"
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include // for exit()
+#include // for stdout
+
+KNewStuff2Test::KNewStuff2Test(const QString& configFile)
+ : QObject()
+{
+ m_messages = new QStandardItemModel(this);
+ m_configFile = configFile;
+ m_engine = NULL;
+ m_testall = false;
+}
+
+void KNewStuff2Test::setTestAll(bool testall)
+{
+ m_testall = testall;
+ emit testAllChanged();
+}
+
+bool KNewStuff2Test::testAll() const
+{
+ return m_testall;
+}
+
+void KNewStuff2Test::entryTest()
+{
+ addMessage(QString::fromLocal8Bit("-- test kns2 entry class"), QStringLiteral("msg_info"));
+
+ QFile f(QString::fromLatin1("%1/testdata/entry.xml").arg(QStringLiteral(KNSSRCDIR)));
+ if (!f.open(QIODevice::ReadOnly)) {
+ addMessage(QString::fromLocal8Bit("Error loading entry file: %1").arg(f.fileName()), QStringLiteral("msg_error"));
+ return;
+ }
+
+ QXmlStreamReader reader(&f);
+ KNSCore::EntryInternal e;
+ reader.readNextStartElement(); // Skip the first (the external OCS container)
+ bool xmlResult = reader.readNextStartElement() && e.setEntryXML(reader);
+ e.setProviderId(QStringLiteral("test-provider"));
+
+ f.close();
+ if(!xmlResult) {
+ addMessage(QString::fromLocal8Bit("Error parsing entry file."), QStringLiteral("msg_error"));
+ return;
+ }
+
+ addMessage(QString::fromLocal8Bit("-- entry->xml test result: %1").arg(e.isValid()), e.isValid() ? QStringLiteral("msg_info") : QStringLiteral("msg_error"));
+ if (!e.isValid()) {
+ return;
+ } else {
+ QTextStream out(stdout);
+ out << e.entryXML();
+ }
+}
+
+void KNewStuff2Test::providerTest()
+{
+ addMessage(QString::fromLocal8Bit("-- test kns2 provider class"), QStringLiteral("msg_info"));
+
+ QDomDocument doc;
+ QFile f(QString::fromLatin1("%1/testdata/provider.xml").arg(QStringLiteral(KNSSRCDIR)));
+ if (!f.open(QIODevice::ReadOnly)) {
+ addMessage(QString::fromLocal8Bit("Error loading provider file: %1").arg(f.fileName()), QStringLiteral("msg_error"));
+ return;
+ }
+ if (!doc.setContent(&f)) {
+ addMessage(QString::fromLocal8Bit("Error parsing provider file: %1").arg(f.fileName()), QStringLiteral("msg_error"));
+ f.close();
+ return;
+ }
+ f.close();
+
+ KNSCore::StaticXmlProvider p;
+ p.setProviderXML(doc.documentElement());
+
+ addMessage(QString::fromLocal8Bit("-- xml->provider test result: %1").arg(p.isInitialized()), p.isInitialized()? QStringLiteral("msg_info") : QStringLiteral("msg_error"));
+
+// QDomElement pxml = p.providerXML();
+
+ // qDebug() << "-- provider->xml test result: " << ph.isValid();
+
+// if (!p.isValid()) {
+// quitTest();
+// } else {
+// QTextStream out(stdout);
+// out << pxml;
+// }
+}
+
+void KNewStuff2Test::engineTest()
+{
+ addMessage(QString::fromLocal8Bit("-- test kns2 engine"), QStringLiteral("msg_info"));
+
+ m_engine = new KNSCore::Engine(this);
+
+ connect(m_engine,
+ &KNSCore::Engine::signalError,
+ this, &KNewStuff2Test::slotEngineError);
+ connect(m_engine,
+ &KNSCore::Engine::signalProvidersLoaded,
+ this, &KNewStuff2Test::slotProvidersLoaded);
+ connect(m_engine,
+ &KNSCore::Engine::signalEntriesLoaded,
+ this, &KNewStuff2Test::slotEntriesLoaded);
+ connect(m_engine,
+ &KNSCore::Engine::signalEntryChanged,
+ this, &KNewStuff2Test::slotInstallationFinished);
+
+ bool ret = m_engine->init(m_configFile);
+
+ addMessage(QString::fromLocal8Bit("-- engine test result: %1").arg(ret), ret ? QStringLiteral("msg_info") : QStringLiteral("msg_error"));
+
+ if (!ret) {
+ addMessage(QString::fromLocal8Bit("ACHTUNG: you probably need to 'make install' the knsrc file first. Although this is not required anymore, so something went really wrong."), QStringLiteral("msg_warning"));
+ }
+ addMessage(QString::fromLocal8Bit("-- initial engine test completed"), QStringLiteral("msg_info"));
+}
+
+void KNewStuff2Test::slotProvidersLoaded()
+{
+ addMessage(QString::fromLocal8Bit("SLOT: slotProvidersLoaded"), QStringLiteral("msg_info"));
+// qDebug() << "-- provider: " << provider->name().representation();
+
+ m_engine->reloadEntries();
+}
+
+void KNewStuff2Test::slotEntriesLoaded(const KNSCore::EntryInternal::List &entries)
+{
+ addMessage(QString::fromLocal8Bit("SLOT: slotEntriesLoaded. Number of entries %1").arg(entries.count()), QStringLiteral("msg_info"));
+
+ if (m_testall) {
+ addMessage(QString::fromLocal8Bit("-- now, download the entries' previews and payload files"), QStringLiteral("msg_info"));
+
+ Q_FOREACH(const KNSCore::EntryInternal& entry, entries) {
+ addMessage(QString::fromLocal8Bit("-- entry: %1").arg(entry.name()), QStringLiteral("msg_info"));
+ if (!entry.previewUrl(KNSCore::EntryInternal::PreviewSmall1).isEmpty()) {
+ m_engine->loadPreview(entry, KNSCore::EntryInternal::PreviewSmall1);
+ }
+ if (!entry.payload().isEmpty()) {
+ m_engine->install(entry);
+ }
+ }
+ }
+}
+
+void KNewStuff2Test::slotInstallationFinished()
+{
+ addMessage(QString::fromLocal8Bit("SLOT: slotInstallationFinished"));
+}
+
+void KNewStuff2Test::slotEngineError(const QString& error)
+{
+ addMessage(QString::fromLocal8Bit("SLOT: slotEngineError %1").arg(error), QStringLiteral("msg_error"));
+}
+
+QObject * KNewStuff2Test::messages()
+{
+ return m_messages;
+}
+
+void KNewStuff2Test::addMessage(const QString& message, const QString& iconName)
+{
+ QStandardItem* item = new QStandardItem(message);
+ item->setData(iconName, Qt::WhatsThisRole);
+ m_messages->appendRow(item);
+}
+
+KNewStuff2Test *test = nullptr;
+static const QtMessageHandler QT_DEFAULT_MESSAGE_HANDLER = qInstallMessageHandler(0);
+void debugOutputHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ if(test) {
+ test->addMessage(msg, QStringLiteral("msg_info"));
+ }
+ // Call the default handler.
+ (*QT_DEFAULT_MESSAGE_HANDLER)(type, context, msg);
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QCommandLineParser* parser = new QCommandLineParser;
+ parser->addHelpOption();
+ parser->addOption(QCommandLineOption(QStringLiteral("testall"), i18n("Downloads all previews and payloads")));
+ parser->addPositionalArgument(QStringLiteral("knsrcfile"), i18n("The KNSRC file you want to use for testing. If none is passed, we will use khotnewstuff_test.knsrc, which must be installed."));
+ parser->process(app);
+
+ if(parser->positionalArguments().count() > 0) {
+ test = new KNewStuff2Test(parser->positionalArguments().first());
+ }
+ else {
+ test = new KNewStuff2Test(QString::fromLatin1("%1/khotnewstuff_test.knsrc").arg(QStringLiteral(KNSBUILDDIR)));
+ }
+ test->setTestAll(parser->isSet(QStringLiteral("testall")));
+
+ QQmlApplicationEngine* appengine = new QQmlApplicationEngine();
+ appengine->rootContext()->setContextProperty(QStringLiteral("testObject"), test);
+ appengine->load(QUrl::fromLocalFile(QString::fromLatin1("%1/khotnewstuff_test-ui/main.qml").arg(QStringLiteral(KNSSRCDIR))));
+
+ // Don't really want to add messages until the tester
+ // begins to actually request stuff in the UI,
+ // so let's just install it here
+ qInstallMessageHandler(debugOutputHandler);
+
+ return app.exec();
+}
diff --git a/tests/knewstuff2_test.knsrc b/tests/khotnewstuff_test.knsrc.in
rename from tests/knewstuff2_test.knsrc
rename to tests/khotnewstuff_test.knsrc.in
--- a/tests/knewstuff2_test.knsrc
+++ b/tests/khotnewstuff_test.knsrc.in
@@ -1,6 +1,7 @@
[KNewStuff2]
#ProvidersUrl=http://edu.kde.org/kalzium/molecules.xml
-ProvidersUrl=http://new.kstuff.org/provider-kalzium.xml
+#ProvidersUrl=http://new.kstuff.org/provider-kalzium.xml
+ProvidersUrl=file://@CMAKE_CURRENT_SOURCE_DIR@/testdata/provider.xml
LocalRegistryDir=/tmp/knewstuff2.metafiles
TargetDir=knewstuff2_test
diff --git a/tests/knewstuff2_test.cpp b/tests/knewstuff2_test.cpp
deleted file mode 100644
--- a/tests/knewstuff2_test.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- This file is part of KNewStuff2.
- Copyright (c) 2007 Josef Spillner
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library. If not, see .
-*/
-
-#include "knewstuff2_test.h"
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-
-#include
-
-#include // for exit()
-#include // for stdout
-
-KNewStuff2Test::KNewStuff2Test()
- : QObject()
-{
- m_engine = NULL;
- m_testall = false;
-}
-
-void KNewStuff2Test::setTestAll(bool testall)
-{
- m_testall = testall;
-}
-
-void KNewStuff2Test::entryTest()
-{
- // qCDebug(KNEWSTUFF) << "-- test kns2 entry class";
-
- QDomDocument doc;
- QFile f(QString("%1/testdata/entry.xml").arg(KNSSRCDIR));
- if (!f.open(QIODevice::ReadOnly)) {
- // qCDebug(KNEWSTUFF) << "Error loading entry file.";
- quitTest();
- }
- if (!doc.setContent(&f)) {
- // qCDebug(KNEWSTUFF) << "Error parsing entry file.";
- f.close();
- quitTest();
- }
- f.close();
-
- KNS::EntryHandler eh(doc.documentElement());
- KNS::Entry e = eh.entry();
-
- // qCDebug(KNEWSTUFF) << "-- xml->entry test result: " << eh.isValid();
-
- KNS::EntryHandler eh2(e);
- QDomElement exml = eh2.entryXML();
-
- // qCDebug(KNEWSTUFF) << "-- entry->xml test result: " << eh.isValid();
-
- if (!eh.isValid()) {
- quitTest();
- } else {
- QTextStream out(stdout);
- out << exml;
- }
-}
-
-void KNewStuff2Test::providerTest()
-{
- // qCDebug(KNEWSTUFF) << "-- test kns2 provider class";
-
- QDomDocument doc;
- QFile f(QString("%1/testdata/provider.xml").arg(KNSSRCDIR));
- if (!f.open(QIODevice::ReadOnly)) {
- // qCDebug(KNEWSTUFF) << "Error loading provider file.";
- quitTest();
- }
- if (!doc.setContent(&f)) {
- // qCDebug(KNEWSTUFF) << "Error parsing provider file.";
- f.close();
- quitTest();
- }
- f.close();
-
- KNS::ProviderHandler ph(doc.documentElement());
- KNS::Provider p = ph.provider();
-
- // qCDebug(KNEWSTUFF) << "-- xml->provider test result: " << ph.isValid();
-
- KNS::ProviderHandler ph2(p);
- QDomElement pxml = ph2.providerXML();
-
- // qCDebug(KNEWSTUFF) << "-- provider->xml test result: " << ph.isValid();
-
- if (!ph.isValid()) {
- quitTest();
- } else {
- QTextStream out(stdout);
- out << pxml;
- }
-}
-
-void KNewStuff2Test::engineTest()
-{
- // qCDebug(KNEWSTUFF) << "-- test kns2 engine";
-
- m_engine = new KNS::CoreEngine(NULL);
- bool ret = m_engine->init("knewstuff2_test.knsrc");
-
- // qCDebug(KNEWSTUFF) << "-- engine test result: " << ret;
-
- if (ret) {
- connect(m_engine,
- &KNS::CoreEngine::signalProviderLoaded,
- this, &KNewStuff2Test::slotProviderLoaded);
- connect(m_engine,
- &KNS::CoreEngine::signalProvidersFailed,
- this, &KNewStuff2Test::slotProvidersFailed);
- connect(m_engine,
- &KNS::CoreEngine::signalEntryLoaded,
- this, &KNewStuff2Test::slotEntryLoaded);
- connect(m_engine,
- &KNS::CoreEngine::signalEntriesFinished,
- this, &KNewStuff2Test::slotEntriesFinished);
- connect(m_engine,
- &KNS::CoreEngine::signalEntriesFailed,
- this, &KNewStuff2Test::slotEntriesFailed);
- connect(m_engine,
- &KNS::CoreEngine::signalPayloadLoaded,
- this, &KNewStuff2Test::slotPayloadLoaded);
- connect(m_engine,
- &KNS::CoreEngine::signalPayloadFailed,
- this, &KNewStuff2Test::slotPayloadFailed);
- connect(m_engine,
- &KNS::CoreEngine::signalInstallationFinished,
- this, &KNewStuff2Test::slotInstallationFinished);
- connect(m_engine,
- &KNS::CoreEngine::signalInstallationFailed,
- this, &KNewStuff2Test::slotInstallationFailed);
-
- m_engine->start();
- } else {
- qWarning() << "ACHTUNG: you probably need to 'make install' the knsrc file first.";
- qWarning() << "Although this is not required anymore, so something went really wrong.";
- quitTest();
- }
-}
-
-void KNewStuff2Test::slotProviderLoaded(KNS::Provider *provider)
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotProviderLoaded";
- // qCDebug(KNEWSTUFF) << "-- provider: " << provider->name().representation();
-
- m_engine->loadEntries(provider);
-}
-
-void KNewStuff2Test::slotEntryLoaded(KNS::Entry *entry, const KNS::Feed *feed, const KNS::Provider *provider)
-{
- Q_UNUSED(feed);
- Q_UNUSED(provider);
-
- // qCDebug(KNEWSTUFF) << "SLOT: slotEntryLoaded";
- // qCDebug(KNEWSTUFF) << "-- entry: " << entry->name().representation();
-
- if (m_testall) {
- // qCDebug(KNEWSTUFF) << "-- now, download the entry's preview and payload file";
-
- if (!entry->preview().isEmpty()) {
- m_engine->downloadPreview(entry);
- }
- if (!entry->payload().isEmpty()) {
- m_engine->downloadPayload(entry);
- }
- }
-}
-
-void KNewStuff2Test::slotEntriesFinished()
-{
- // Wait for installation if requested
- if (!m_testall) {
- quitTest();
- }
-}
-
-void KNewStuff2Test::slotPayloadLoaded(QUrl payload)
-{
- // qCDebug(KNEWSTUFF) << "-- entry downloaded successfully";
- // qCDebug(KNEWSTUFF) << "-- downloaded to " << payload.prettyUrl();
-
- // qCDebug(KNEWSTUFF) << "-- run installation";
-
- bool ret = m_engine->install(payload.path());
-
- // qCDebug(KNEWSTUFF) << "-- installation result: " << ret;
- // qCDebug(KNEWSTUFF) << "-- now, wait for installation to finish...";
-}
-
-void KNewStuff2Test::slotPayloadFailed()
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotPayloadFailed";
- quitTest();
-}
-
-void KNewStuff2Test::slotProvidersFailed()
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotProvidersFailed";
- quitTest();
-}
-
-void KNewStuff2Test::slotEntriesFailed()
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotEntriesFailed";
- quitTest();
-}
-
-void KNewStuff2Test::slotInstallationFinished()
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotInstallationFinished";
- // qCDebug(KNEWSTUFF) << "-- OK, finish test";
- quitTest();
-}
-
-void KNewStuff2Test::slotInstallationFailed()
-{
- // qCDebug(KNEWSTUFF) << "SLOT: slotInstallationFailed";
- quitTest();
-}
-
-void KNewStuff2Test::quitTest()
-{
- // qCDebug(KNEWSTUFF) << "-- quitting now...";
- if (1 == 0) {
- // this would be the soft way out...
- delete m_engine;
- deleteLater();
- qApp->quit();
- } else {
- exit(1);
- }
-}
-
-int main(int argc, char **argv)
-{
- //options.add("testall", qi18n("Downloads all previews and payloads"));
-
- QApplication app(argc, argv);
-
- // Take source directory into account
- // qCDebug(KNEWSTUFF) << "-- adding source directory " << KNSSRCDIR;
- // qCDebug(KNEWSTUFF) << "-- adding build directory " << KNSBUILDDIR;
- KGlobal::dirs()->addResourceDir("config", KNSSRCDIR);
- KGlobal::dirs()->addResourceDir("config", KNSBUILDDIR);
-
- KNewStuff2Test *test = new KNewStuff2Test();
- if (app.arguments().contains("--testall")) {
- test->setTestAll(true);
- test->entryTest();
- test->providerTest();
- }
- test->engineTest();
-
- return app.exec();
-}
-
diff --git a/tests/testdata/entry.xml b/tests/testdata/entry.xml
--- a/tests/testdata/entry.xml
+++ b/tests/testdata/entry.xml
@@ -1,14 +1,55 @@
-
- Some Name
- Anonymous Guy
- GPL
- 1.0
- 2005-06-17
- This is what it is all about.
- http://some.http.server/preview.png
- http://some.http.server/coolstuff.tar.gz
- 10
- 0
-
-
+
+
+ Entry 1 (ghns excluded)
+ Anonymous Guy
+ GPL
+ 1.0
+ 2005-06-17
+ This is what it is all about.
+ http://some.http.server/preview.png
+ http://some.http.server/coolstuff.tar.gz
+ 10
+ 0
+ ghns_exclude=1
+
+
+ Entry 2 (ghns included)
+ Anonymous Guy
+ GPL
+ 2.1git2
+ 2018-06-05
+ A short description in English (not ghns excluded).
+ http://some.http.server/preview.png
+ http://some.http.server/coolstuff.tar.gz
+ 10
+ 0
+
+
+
+ Entry 3 (ghns excluded)
+ Anonymous Guy
+ GPL
+ 1.0
+ 2005-06-17
+ This is what it is all about.
+ http://some.http.server/preview.png
+ http://some.http.server/coolstuff.tar.gz
+ 10
+ 0
+ ghns_exclude=1
+
+
+ Entry 4 (ghns included)
+ Anonymous Guy
+ GPL
+ 2.1git2
+ 2018-06-05
+ A short description in English (not ghns excluded).
+ http://some.http.server/preview.png
+ http://some.http.server/coolstuff.tar.gz
+ 10
+ 0
+
+
+
diff --git a/tests/testdata/provider.xml b/tests/testdata/provider.xml
--- a/tests/testdata/provider.xml
+++ b/tests/testdata/provider.xml
@@ -1,12 +1,22 @@
-
+
+
Some cool stuff
Viele neue Dinge
+