mirror of
https://bitbucket.org/smil3y/kdelibs.git
synced 2025-02-23 18:32:49 +00:00
507 lines
21 KiB
C++
507 lines
21 KiB
C++
![]() |
/* This file is part of the KDE libraries
|
||
|
Copyright (c) 2008 David Faure <faure@kde.org>
|
||
|
|
||
|
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 of the License or ( at
|
||
|
your option ) version 3 or, at the discretion of KDE e.V. ( which shall
|
||
|
act as a proxy as in section 14 of the GPLv3 ), 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
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Lesser General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include <kprocess.h>
|
||
|
#include <kconfiggroup.h>
|
||
|
#include <kdesktopfile.h>
|
||
|
#include <kmimetypetrader.h>
|
||
|
#include <kdebug.h>
|
||
|
#include <kservicefactory.h>
|
||
|
#include <ktemporaryfile.h>
|
||
|
#include <qtest_kde.h>
|
||
|
#include "kmimeassociations.h"
|
||
|
#include <ksycoca.h>
|
||
|
#include <kstandarddirs.h>
|
||
|
|
||
|
// We need a factory that returns the same KService::Ptr every time it's asked for a given service.
|
||
|
// Otherwise the changes to the service's serviceTypes by KMimeAssociationsTest have no effect
|
||
|
class FakeServiceFactory : public KServiceFactory
|
||
|
{
|
||
|
public:
|
||
|
FakeServiceFactory() : KServiceFactory() {}
|
||
|
|
||
|
virtual KService::Ptr findServiceByMenuId(const QString &name) {
|
||
|
//kDebug() << name;
|
||
|
KService::Ptr result = m_cache.value(name);
|
||
|
if (!result) {
|
||
|
result = KServiceFactory::findServiceByMenuId(name);
|
||
|
m_cache.insert(name, result);
|
||
|
}
|
||
|
//kDebug() << name << result.data();
|
||
|
return result;
|
||
|
}
|
||
|
virtual KService::Ptr findServiceByDesktopPath(const QString &name)
|
||
|
{
|
||
|
KService::Ptr result = m_cache.value(name); // yeah, same cache, I don't care :)
|
||
|
if (!result) {
|
||
|
result = KServiceFactory::findServiceByDesktopPath(name);
|
||
|
m_cache.insert(name, result);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
private:
|
||
|
QMap<QString, KService::Ptr> m_cache;
|
||
|
};
|
||
|
|
||
|
// Helper method for all the trader tests, comes from kmimetypetest.cpp
|
||
|
static bool offerListHasService( const KService::List& offers,
|
||
|
const QString& entryPath,
|
||
|
bool expected /* if set, show error if not found */ )
|
||
|
{
|
||
|
bool found = false;
|
||
|
Q_FOREACH(const KService::Ptr &serv, offers) {
|
||
|
if ( serv->entryPath() == entryPath ) {
|
||
|
if( found ) { // should be there only once
|
||
|
qWarning( "ERROR: %s was found twice in the list", qPrintable( entryPath ) );
|
||
|
return false; // make test fail
|
||
|
}
|
||
|
found = true;
|
||
|
}
|
||
|
}
|
||
|
if (!found && expected) {
|
||
|
kWarning() << "ERROR:" << entryPath << "not found in offer list. Here's the full list:";
|
||
|
Q_FOREACH(const KService::Ptr &serv, offers) {
|
||
|
kDebug() << serv->entryPath();
|
||
|
}
|
||
|
}
|
||
|
return found;
|
||
|
}
|
||
|
|
||
|
static void writeAppDesktopFile(const QString& path, const QStringList& mimeTypes, int initialPreference = 1)
|
||
|
{
|
||
|
KDesktopFile file(path);
|
||
|
KConfigGroup group = file.desktopGroup();
|
||
|
group.writeEntry("Name", "FakeApplication");
|
||
|
group.writeEntry("Type", "Application");
|
||
|
group.writeEntry("Exec", "ls");
|
||
|
group.writeEntry("InitialPreference", initialPreference);
|
||
|
group.writeXdgListEntry("MimeType", mimeTypes);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* This unit test verifies the parsing of mimeapps.list files, both directly
|
||
|
* and via kbuildsycoca (and making trader queries).
|
||
|
*/
|
||
|
class KMimeAssociationsTest : public QObject
|
||
|
{
|
||
|
Q_OBJECT
|
||
|
private Q_SLOTS:
|
||
|
void initTestCase()
|
||
|
{
|
||
|
QString kdehome = QDir::home().canonicalPath() + "/.kde-unit-test";
|
||
|
m_localApps = KStandardDirs::locateLocal("xdgdata-apps", "");
|
||
|
QVERIFY(m_localApps.startsWith(kdehome));
|
||
|
|
||
|
// Create factory on the heap and don't delete it.
|
||
|
// It registers to KSycoca, which deletes it at end of program execution.
|
||
|
KServiceFactory* factory = new FakeServiceFactory;
|
||
|
QCOMPARE(KServiceFactory::self(), factory); // ctor sets s_self
|
||
|
bool mustUpdateKSycoca = false;
|
||
|
if ( !KSycoca::isAvailable() ) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
}
|
||
|
if (QFile::exists(m_localApps + "/mimeapps.list")) {
|
||
|
QFile::remove(m_localApps + "/mimeapps.list");
|
||
|
mustUpdateKSycoca = true;
|
||
|
}
|
||
|
|
||
|
// Create fake application (associated with text/plain in mimeapps.list)
|
||
|
fakeTextApplication = m_localApps + "faketextapplication.desktop";
|
||
|
if (!QFile::exists(fakeTextApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeTextApplication, QStringList() << "text/plain");
|
||
|
}
|
||
|
|
||
|
// A fake "default" application for text/plain (high initial preference, but not in mimeapps.list)
|
||
|
fakeDefaultTextApplication = m_localApps + "fakedefaulttextapplication.desktop";
|
||
|
if (!QFile::exists(fakeDefaultTextApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeDefaultTextApplication, QStringList() << "text/plain", 9);
|
||
|
}
|
||
|
|
||
|
// An app (like emacs) listing explicitely the derived mimetype (c-src); not in mimeapps.list
|
||
|
// This interacted badly with mimeapps.list listing another app for text/plain, but the
|
||
|
// lookup found this app first, due to c-src. The fix: ignoring derived mimetypes when
|
||
|
// the base mimetype is already listed.
|
||
|
//
|
||
|
// Also include aliases (msword), to check they don't cancel each other out.
|
||
|
fakeCSrcApplication = m_localApps + "fakecsrcapplication.desktop";
|
||
|
if (!QFile::exists(fakeCSrcApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeCSrcApplication, QStringList() << "text/plain" << "text/c-src" << "application/vnd.ms-word" << "application/msword", 8);
|
||
|
}
|
||
|
|
||
|
fakeJpegApplication = m_localApps + "fakejpegapplication.desktop";
|
||
|
if (!QFile::exists(fakeJpegApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeJpegApplication, QStringList() << "image/jpeg");
|
||
|
}
|
||
|
|
||
|
fakeArkApplication = m_localApps + "fakearkapplication.desktop";
|
||
|
if (!QFile::exists(fakeArkApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeArkApplication, QStringList() << "application/zip");
|
||
|
}
|
||
|
|
||
|
fakeHtmlApplication = m_localApps + "fakehtmlapplication.desktop";
|
||
|
if (!QFile::exists(fakeHtmlApplication)) {
|
||
|
mustUpdateKSycoca = true;
|
||
|
writeAppDesktopFile(fakeHtmlApplication, QStringList() << "text/html");
|
||
|
}
|
||
|
|
||
|
|
||
|
if ( mustUpdateKSycoca ) {
|
||
|
// Update ksycoca in ~/.kde-unit-test after creating the above
|
||
|
runKBuildSycoca();
|
||
|
}
|
||
|
|
||
|
// For debugging: print all services and their storageId
|
||
|
#if 0
|
||
|
const KService::List lst = KService::allServices();
|
||
|
QVERIFY( !lst.isEmpty() );
|
||
|
Q_FOREACH(const KService::Ptr& serv, lst) {
|
||
|
qDebug() << serv->entryPath() << serv->storageId() /*<< serv->desktopEntryName()*/;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
KService::Ptr fakeApplicationService = KService::serviceByStorageId("faketextapplication.desktop");
|
||
|
QVERIFY(fakeApplicationService);
|
||
|
|
||
|
m_mimeAppsFileContents = "[Added Associations]\n"
|
||
|
"image/jpeg=fakejpegapplication.desktop;\n"
|
||
|
"text/html=fakehtmlapplication.desktop;\n"
|
||
|
// konsole.desktop is without kde4- to test fallback lookup
|
||
|
"text/plain=faketextapplication.desktop;kde4-kwrite.desktop;konsole.desktop;idontexist.desktop;\n"
|
||
|
// test alias resolution
|
||
|
"application/x-pdf=fakejpegapplication.desktop;\n"
|
||
|
"[Added KParts/ReadOnlyPart Associations]\n"
|
||
|
"text/plain=katepart.desktop;\n"
|
||
|
"[Removed Associations]\n"
|
||
|
"image/jpeg=firefox.desktop;\n"
|
||
|
"text/html=kde4-dolphin.desktop;kde4-kwrite.desktop;\n";
|
||
|
// Expected results
|
||
|
preferredApps["image/jpeg"] << "fakejpegapplication.desktop";
|
||
|
preferredApps["application/pdf"] << "fakejpegapplication.desktop";
|
||
|
preferredApps["text/plain"] << "faketextapplication.desktop" << "kde4-kwrite.desktop";
|
||
|
preferredApps["text/x-csrc"] << "faketextapplication.desktop" << "kde4-kwrite.desktop";
|
||
|
preferredApps["text/html"] << "fakehtmlapplication.desktop";
|
||
|
preferredApps["application/msword"] << "fakecsrcapplication.desktop";
|
||
|
removedApps["image/jpeg"] << "firefox.desktop";
|
||
|
removedApps["text/html"] << "kde4-dolphin.desktop" << "kde4-kwrite.desktop";
|
||
|
|
||
|
// Clean-up non-existing apps
|
||
|
removeNonExisting(preferredApps);
|
||
|
removeNonExisting(removedApps);
|
||
|
}
|
||
|
|
||
|
void cleanupTestCase()
|
||
|
{
|
||
|
QFile::remove(m_localApps + "/mimeapps.list");
|
||
|
runKBuildSycoca();
|
||
|
}
|
||
|
|
||
|
void testParseSingleFile()
|
||
|
{
|
||
|
KOfferHash offerHash;
|
||
|
KMimeAssociations parser(offerHash);
|
||
|
|
||
|
KTemporaryFile tempFile;
|
||
|
QVERIFY(tempFile.open());
|
||
|
tempFile.write(m_mimeAppsFileContents);
|
||
|
const QString fileName = tempFile.fileName();
|
||
|
tempFile.close();
|
||
|
|
||
|
//QTest::ignoreMessage(QtDebugMsg, "findServiceByDesktopPath: idontexist.desktop not found");
|
||
|
parser.parseMimeAppsList(fileName, 100);
|
||
|
|
||
|
for (ExpectedResultsMap::const_iterator it = preferredApps.constBegin(),
|
||
|
end = preferredApps.constEnd() ; it != end ; ++it) {
|
||
|
const QString mime = it.key();
|
||
|
// The data for derived types and aliases isn't for this test (which only looks at mimeapps.list)
|
||
|
if (mime == QLatin1String("text/x-csrc") || mime == QLatin1String("application/msword"))
|
||
|
continue;
|
||
|
const QList<KServiceOffer> offers = offerHash.offersFor(mime);
|
||
|
Q_FOREACH(const QString& service, it.value()) {
|
||
|
KService::Ptr serv = KService::serviceByStorageId(service);
|
||
|
if (serv && !offersContains(offers, serv)) {
|
||
|
kDebug() << "expected offer" << serv->entryPath() << "not in offers for" << mime << ":";
|
||
|
Q_FOREACH(const KServiceOffer& offer, offers) {
|
||
|
kDebug() << offer.service()->storageId();
|
||
|
}
|
||
|
QFAIL("offer does not have servicetype");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (ExpectedResultsMap::const_iterator it = removedApps.constBegin(),
|
||
|
end = removedApps.constEnd() ; it != end ; ++it) {
|
||
|
const QString mime = it.key();
|
||
|
const QList<KServiceOffer> offers = offerHash.offersFor(mime);
|
||
|
Q_FOREACH(const QString& service, it.value()) {
|
||
|
KService::Ptr serv = KService::serviceByStorageId(service);
|
||
|
if (serv && offersContains(offers, serv)) {
|
||
|
kDebug() << serv.data() << serv->entryPath() << "does not have" << mime;
|
||
|
QFAIL("offer should not have servicetype");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void testGlobalAndLocalFiles()
|
||
|
{
|
||
|
KOfferHash offerHash;
|
||
|
KMimeAssociations parser(offerHash);
|
||
|
|
||
|
// Write global file
|
||
|
KTemporaryFile tempFileGlobal;
|
||
|
QVERIFY(tempFileGlobal.open());
|
||
|
QByteArray globalAppsFileContents = "[Added Associations]\n"
|
||
|
"image/jpeg=firefox.desktop;\n" // removed by local config
|
||
|
"text/html=firefox.desktop;\n" // mdv
|
||
|
"image/png=fakejpegapplication.desktop;\n";
|
||
|
tempFileGlobal.write(globalAppsFileContents);
|
||
|
const QString globalFileName = tempFileGlobal.fileName();
|
||
|
tempFileGlobal.close();
|
||
|
|
||
|
// We didn't keep it, so we need to write the local file again
|
||
|
KTemporaryFile tempFile;
|
||
|
QVERIFY(tempFile.open());
|
||
|
tempFile.write(m_mimeAppsFileContents);
|
||
|
const QString fileName = tempFile.fileName();
|
||
|
tempFile.close();
|
||
|
|
||
|
parser.parseMimeAppsList(globalFileName, 1000);
|
||
|
parser.parseMimeAppsList(fileName, 1050); // += 50 is correct.
|
||
|
|
||
|
QList<KServiceOffer> offers = offerHash.offersFor("image/jpeg");
|
||
|
qStableSort(offers); // like kbuildservicefactory.cpp does
|
||
|
const QStringList expectedJpegApps = preferredApps["image/jpeg"];
|
||
|
QCOMPARE(assembleOffers(offers), expectedJpegApps);
|
||
|
|
||
|
offers = offerHash.offersFor("text/html");
|
||
|
qStableSort(offers);
|
||
|
QStringList textHtmlApps = preferredApps["text/html"];
|
||
|
if (KService::serviceByStorageId("firefox.desktop"))
|
||
|
textHtmlApps.append("firefox.desktop");
|
||
|
qDebug() << assembleOffers(offers);
|
||
|
QCOMPARE(assembleOffers(offers), textHtmlApps);
|
||
|
|
||
|
offers = offerHash.offersFor("image/png");
|
||
|
qStableSort(offers);
|
||
|
QCOMPARE(assembleOffers(offers), QStringList() << "fakejpegapplication.desktop");
|
||
|
}
|
||
|
|
||
|
void testSetupRealFile()
|
||
|
{
|
||
|
writeToMimeApps(m_mimeAppsFileContents);
|
||
|
|
||
|
// Test a trader query
|
||
|
KService::List offers = KMimeTypeTrader::self()->query("image/jpeg");
|
||
|
//kDebug() << m_mimeAppsFileContents;
|
||
|
//kDebug() << "preferred apps for jpeg: " << preferredApps.value("image/jpeg");
|
||
|
//for (int i = 0; i < offers.count(); ++i) {
|
||
|
// kDebug() << "offers for" << "image/jpeg" << ":" << i << offers[i]->storageId();
|
||
|
//}
|
||
|
QCOMPARE(offers.first()->storageId(), QString("fakejpegapplication.desktop"));
|
||
|
|
||
|
// Now the generic variant of the above test:
|
||
|
// for each mimetype, check that the preferred apps are as specified
|
||
|
for (ExpectedResultsMap::const_iterator it = preferredApps.constBegin(), end = preferredApps.constEnd() ; it != end ; ++it) {
|
||
|
const QString mime = it.key();
|
||
|
kDebug() << "offers for" << mime << ":";
|
||
|
const KService::List offers = KMimeTypeTrader::self()->query(mime);
|
||
|
for (int i = 0; i < offers.count(); ++i) {
|
||
|
kDebug() << " " << i << ":" << offers[i]->storageId();
|
||
|
}
|
||
|
const QStringList offerIds = assembleServices(offers, it.value().count());
|
||
|
kDebug() << " Expected:" << it.value();
|
||
|
QCOMPARE(offerIds, it.value());
|
||
|
//const QStringList expectedPreferredServices = it.value();
|
||
|
//for (int i = 0; i < expectedPreferredServices.count(); ++i) {
|
||
|
//kDebug() << mime << i << expectedPreferredServices[i];
|
||
|
// QCOMPARE(expectedPreferredServices[i], offers[i]->storageId());
|
||
|
//}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void testMultipleInheritance()
|
||
|
{
|
||
|
// application/x-shellscript inherits from both text/plain and application/x-executable
|
||
|
KService::List offers = KMimeTypeTrader::self()->query("application/x-shellscript");
|
||
|
QVERIFY(offerListHasService(offers, fakeTextApplication, true));
|
||
|
}
|
||
|
|
||
|
void testRemoveAssociationFromParent()
|
||
|
{
|
||
|
// I removed kate from text/plain, and it would still appear in text/x-java.
|
||
|
|
||
|
// First, let's check our fake app is associated with text/plain
|
||
|
KService::List offers = KMimeTypeTrader::self()->query("text/plain");
|
||
|
QVERIFY(offerListHasService(offers, fakeTextApplication, true));
|
||
|
|
||
|
writeToMimeApps(QByteArray("[Removed Associations]\n"
|
||
|
"text/plain=faketextapplication.desktop;\n"));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("text/plain");
|
||
|
QVERIFY(!offerListHasService(offers, fakeTextApplication, false));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("text/x-java");
|
||
|
QVERIFY(!offerListHasService(offers, fakeTextApplication, false));
|
||
|
}
|
||
|
|
||
|
void testRemovedImplicitAssociation() // remove (implicit) assoc from derived mimetype
|
||
|
{
|
||
|
// #164584: Removing ark from opendocument.text didn't work
|
||
|
const QString opendocument = "application/vnd.oasis.opendocument.text";
|
||
|
KService::List offers = KMimeTypeTrader::self()->query(opendocument);
|
||
|
QVERIFY(offerListHasService(offers, fakeArkApplication, true));
|
||
|
|
||
|
writeToMimeApps(QByteArray("[Removed Associations]\n"
|
||
|
"application/vnd.oasis.opendocument.text=fakearkapplication.desktop;\n"));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query(opendocument);
|
||
|
QVERIFY(!offerListHasService(offers, fakeArkApplication, false));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("application/zip");
|
||
|
QVERIFY(offerListHasService(offers, fakeArkApplication, true));
|
||
|
}
|
||
|
|
||
|
void testRemovedImplicitAssociation178560()
|
||
|
{
|
||
|
// #178560: Removing ark from interface/x-winamp-skin didn't work
|
||
|
// Using application/x-kns (another zip-derived mimetype) nowadays.
|
||
|
const QString mime = "application/x-kns";
|
||
|
KService::List offers = KMimeTypeTrader::self()->query(mime);
|
||
|
QVERIFY(offerListHasService(offers, fakeArkApplication, true));
|
||
|
|
||
|
writeToMimeApps(QByteArray("[Removed Associations]\n"
|
||
|
"application/x-kns=fakearkapplication.desktop;\n"));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query(mime);
|
||
|
QVERIFY(!offerListHasService(offers, fakeArkApplication, false));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("application/zip");
|
||
|
QVERIFY(offerListHasService(offers, fakeArkApplication, true));
|
||
|
}
|
||
|
|
||
|
// remove assoc from a mime which is both a parent and a derived mimetype
|
||
|
void testRemovedMiddleAssociation()
|
||
|
{
|
||
|
// More tricky: x-theme inherits x-desktop inherits text/plain,
|
||
|
// if we remove an association for x-desktop then x-theme shouldn't
|
||
|
// get it from text/plain...
|
||
|
|
||
|
KService::List offers;
|
||
|
writeToMimeApps(QByteArray("[Removed Associations]\n"
|
||
|
"application/x-desktop=faketextapplication.desktop;\n"));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("text/plain");
|
||
|
QVERIFY(offerListHasService(offers, fakeTextApplication, true));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("application/x-desktop");
|
||
|
QVERIFY(!offerListHasService(offers, fakeTextApplication, false));
|
||
|
|
||
|
offers = KMimeTypeTrader::self()->query("application/x-theme");
|
||
|
QVERIFY(!offerListHasService(offers, fakeTextApplication, false));
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
typedef QMap<QString /*mimetype*/, QStringList> ExpectedResultsMap;
|
||
|
|
||
|
void runKBuildSycoca()
|
||
|
{
|
||
|
//kDebug();
|
||
|
// Wait for notifyDatabaseChanged DBus signal
|
||
|
// (The real KCM code simply does the refresh in a slot, asynchronously)
|
||
|
QEventLoop loop;
|
||
|
QObject::connect(KSycoca::self(), SIGNAL(databaseChanged(QStringList)), &loop, SLOT(quit()));
|
||
|
KProcess proc;
|
||
|
const QString kbuildsycoca = KStandardDirs::findExe(KBUILDSYCOCA_EXENAME);
|
||
|
QVERIFY(!kbuildsycoca.isEmpty());
|
||
|
proc << kbuildsycoca;
|
||
|
proc.setOutputChannelMode(KProcess::MergedChannels); // silence kbuildsycoca output
|
||
|
proc.execute();
|
||
|
loop.exec();
|
||
|
}
|
||
|
|
||
|
void writeToMimeApps(const QByteArray& contents)
|
||
|
{
|
||
|
QString mimeAppsPath = m_localApps + "/mimeapps.list";
|
||
|
QFile mimeAppsFile(mimeAppsPath);
|
||
|
QVERIFY(mimeAppsFile.open(QIODevice::WriteOnly));
|
||
|
mimeAppsFile.write(contents);
|
||
|
mimeAppsFile.close();
|
||
|
|
||
|
runKBuildSycoca();
|
||
|
}
|
||
|
|
||
|
static bool offersContains(const QList<KServiceOffer>& offers, KService::Ptr serv)
|
||
|
{
|
||
|
Q_FOREACH(const KServiceOffer& offer, offers) {
|
||
|
if (offer.service()->storageId() == serv->storageId())
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
static QStringList assembleOffers(const QList<KServiceOffer>& offers) {
|
||
|
QStringList lst;
|
||
|
Q_FOREACH(const KServiceOffer& offer, offers) {
|
||
|
lst.append(offer.service()->storageId());
|
||
|
}
|
||
|
return lst;
|
||
|
}
|
||
|
static QStringList assembleServices(const QList<KService::Ptr>& services, int maxCount = -1) {
|
||
|
QStringList lst;
|
||
|
Q_FOREACH(const KService::Ptr& service, services) {
|
||
|
lst.append(service->storageId());
|
||
|
if (maxCount > -1 && lst.count() == maxCount)
|
||
|
break;
|
||
|
}
|
||
|
return lst;
|
||
|
}
|
||
|
|
||
|
void removeNonExisting(ExpectedResultsMap& erm) {
|
||
|
for (ExpectedResultsMap::iterator it = erm.begin(), end = erm.end() ; it != end ; ++it) {
|
||
|
QMutableStringListIterator serv_it( it.value() );
|
||
|
while (serv_it.hasNext()) {
|
||
|
if (!KService::serviceByStorageId(serv_it.next())) {
|
||
|
kDebug() << "removing non-existing entry" << serv_it.value();
|
||
|
serv_it.remove();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
QString m_localApps;
|
||
|
QByteArray m_mimeAppsFileContents;
|
||
|
QString fakeTextApplication;
|
||
|
QString fakeDefaultTextApplication;
|
||
|
QString fakeCSrcApplication;
|
||
|
QString fakeJpegApplication;
|
||
|
QString fakeHtmlApplication;
|
||
|
QString fakeArkApplication;
|
||
|
|
||
|
ExpectedResultsMap preferredApps;
|
||
|
ExpectedResultsMap removedApps;
|
||
|
};
|
||
|
|
||
|
QTEST_KDEMAIN_CORE( KMimeAssociationsTest )
|
||
|
|
||
|
#include "kmimeassociationstest.moc"
|