cf12defd28
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1338 lines
50 KiB
C++
1338 lines
50 KiB
C++
/*
|
|
This file is part of the KDE project
|
|
SPDX-FileCopyrightText: 2007 Kevin Ottens <ervin@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-only
|
|
*/
|
|
|
|
#ifdef WITH_QTDBUS
|
|
#include <QDBusInterface>
|
|
#endif
|
|
|
|
#include <QDebug>
|
|
#include <QObject>
|
|
#include <QSignalSpy>
|
|
#include <QTemporaryDir>
|
|
#include <QTest>
|
|
|
|
#include <KBookmark>
|
|
#include <KBookmarkManager>
|
|
#include <KConfig>
|
|
#include <KConfigGroup>
|
|
#include <KProtocolInfo>
|
|
#include <QStandardPaths>
|
|
#include <kfileplacesmodel.h>
|
|
#include <solid/device.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
Q_DECLARE_METATYPE(KFilePlacesModel::GroupType)
|
|
|
|
// Avoid QHash randomization so that the order of the devices is stable
|
|
static void seedInit()
|
|
{
|
|
qputenv("QT_HASH_SEED", "0");
|
|
// This env var has no effect because this comes too late. qCpuFeatures() was already called by
|
|
// a Q_CONSTRUCTOR_FUNCTION inside QtGui (see image/qimage_conversions.cpp). Argh. QTBUG-47566.
|
|
qputenv("QT_NO_CPU_FEATURE", "sse4.2");
|
|
}
|
|
Q_CONSTRUCTOR_FUNCTION(seedInit)
|
|
|
|
class KFilePlacesModelTest : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
private Q_SLOTS:
|
|
void initTestCase();
|
|
void cleanupTestCase();
|
|
|
|
void testInitialList();
|
|
void testAddingInLaterVersion_data();
|
|
void testAddingInLaterVersion();
|
|
void testReparse();
|
|
void testInternalBookmarksHaveIds();
|
|
void testHiding();
|
|
void testMove();
|
|
void testPlacesLifecycle();
|
|
void testDevicePlugging();
|
|
void testDragAndDrop();
|
|
void testDeviceSetupTeardown();
|
|
void testEnableBaloo();
|
|
void testRemoteUrls_data();
|
|
void testRemoteUrls();
|
|
void testRefresh();
|
|
void testConvertedUrl_data();
|
|
void testConvertedUrl();
|
|
void testBookmarkObject();
|
|
void testDataChangedSignal();
|
|
void testIconRole_data();
|
|
void testIconRole();
|
|
void testMoveFunction();
|
|
void testPlaceGroupHidden();
|
|
void testPlaceGroupHiddenVsPlaceChildShown();
|
|
void testPlaceGroupHiddenAndShownWithHiddenChild();
|
|
void testPlaceGroupHiddenGroupIndexesIntegrity();
|
|
void testPlaceGroupHiddenSignal();
|
|
void testPlaceGroupHiddenRole();
|
|
void testSupportedSchemes();
|
|
|
|
private:
|
|
QStringList placesUrls(KFilePlacesModel *model = nullptr) const;
|
|
#ifdef WITH_QTDBUS
|
|
QDBusInterface *fakeManager();
|
|
QDBusInterface *fakeDevice(const QString &udi);
|
|
#endif
|
|
void createPlacesModels();
|
|
|
|
KFilePlacesModel *m_places;
|
|
KFilePlacesModel *m_places2; // To check that they always stay in sync
|
|
// actually supposed to work across processes,
|
|
// but much harder to test
|
|
#ifdef WITH_QTDBUS
|
|
QMap<QString, QDBusInterface *> m_interfacesMap;
|
|
#endif
|
|
|
|
QTemporaryDir m_tmpHome;
|
|
bool m_hasRecentlyUsedKio;
|
|
};
|
|
|
|
static QString bookmarksFile()
|
|
{
|
|
return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/user-places.xbel");
|
|
}
|
|
|
|
void KFilePlacesModelTest::initTestCase()
|
|
{
|
|
QVERIFY(m_tmpHome.isValid());
|
|
qputenv("HOME", m_tmpHome.path().toUtf8()); // use a empty home dir
|
|
|
|
QStandardPaths::setTestModeEnabled(true);
|
|
|
|
// Ensure we'll have a clean bookmark file to start
|
|
QFile::remove(bookmarksFile());
|
|
|
|
// disable baloo by default
|
|
KConfig config(QStringLiteral("baloofilerc"));
|
|
KConfigGroup basicSettings = config.group(QStringLiteral("Basic Settings"));
|
|
basicSettings.writeEntry("Indexing-Enabled", false);
|
|
config.sync();
|
|
|
|
qRegisterMetaType<QModelIndex>();
|
|
qRegisterMetaType<KFilePlacesModel::GroupType>();
|
|
|
|
const QString fakeHw = QFINDTESTDATA("fakecomputer.xml");
|
|
QVERIFY(!fakeHw.isEmpty());
|
|
qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw));
|
|
m_hasRecentlyUsedKio = qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"));
|
|
|
|
createPlacesModels();
|
|
}
|
|
|
|
void KFilePlacesModelTest::createPlacesModels()
|
|
{
|
|
KBookmarkManager mgr(bookmarksFile());
|
|
QSignalSpy spy(&mgr, &KBookmarkManager::changed);
|
|
m_places = new KFilePlacesModel();
|
|
m_places2 = new KFilePlacesModel();
|
|
|
|
// When the xbel file is empty, KFilePlacesModel fills it with 3 default items
|
|
// 5 when KIO worker recentlyused:/ is installed
|
|
QCOMPARE(m_places->rowCount(), m_hasRecentlyUsedKio ? 5 : 3);
|
|
|
|
QVERIFY(spy.wait());
|
|
|
|
// Devices have a delayed loading. Waiting for KDirWatch also waits for that to happen
|
|
QCOMPARE(m_places->rowCount(), m_hasRecentlyUsedKio ? 10 : 8);
|
|
}
|
|
|
|
void KFilePlacesModelTest::cleanupTestCase()
|
|
{
|
|
delete m_places;
|
|
delete m_places2;
|
|
#ifdef WITH_QTDBUS
|
|
qDeleteAll(m_interfacesMap);
|
|
#endif
|
|
QFile::remove(bookmarksFile());
|
|
}
|
|
|
|
QStringList KFilePlacesModelTest::placesUrls(KFilePlacesModel *model) const
|
|
{
|
|
KFilePlacesModel *currentModel = model;
|
|
if (!currentModel) {
|
|
currentModel = m_places;
|
|
}
|
|
QStringList urls;
|
|
for (int row = 0; row < currentModel->rowCount(); ++row) {
|
|
QModelIndex index = currentModel->index(row, 0);
|
|
urls << currentModel->url(index).toDisplayString(QUrl::PreferLocalFile);
|
|
}
|
|
return urls;
|
|
}
|
|
|
|
/* clang-format off */
|
|
#define CHECK_PLACES_URLS(urls) \
|
|
if (placesUrls() != urls) { \
|
|
qDebug() << "Expected:" << urls; \
|
|
qDebug() << "Got:" << placesUrls(); \
|
|
QCOMPARE(placesUrls(), urls); \
|
|
} \
|
|
QCOMPARE(urls.size(), m_places->rowCount()); \
|
|
QCOMPARE(urls.size(), m_places2->rowCount()); \
|
|
for (int row = 0; row < urls.size(); ++row) { \
|
|
QModelIndex index = m_places->index(row, 0); \
|
|
\
|
|
QCOMPARE(m_places->url(index).toString(), QUrl::fromUserInput(urls[row]).toString()); \
|
|
QCOMPARE(m_places->data(index, KFilePlacesModel::UrlRole).toUrl(), QUrl(m_places->url(index))); \
|
|
\
|
|
index = m_places2->index(row, 0); \
|
|
\
|
|
QCOMPARE(m_places2->url(index).toString(), QUrl::fromUserInput(urls[row]).toString()); \
|
|
QCOMPARE(m_places2->data(index, KFilePlacesModel::UrlRole).toUrl(), QUrl(m_places2->url(index))); \
|
|
} \
|
|
/*clang-format on */
|
|
|
|
#ifdef WITH_QTDBUS
|
|
QDBusInterface *KFilePlacesModelTest::fakeManager()
|
|
{
|
|
return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
|
|
}
|
|
|
|
QDBusInterface *KFilePlacesModelTest::fakeDevice(const QString &udi)
|
|
{
|
|
QDBusInterface *interface = m_interfacesMap[udi];
|
|
if (interface) {
|
|
return interface;
|
|
}
|
|
|
|
QDBusInterface *iface = new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi);
|
|
m_interfacesMap[udi] = iface;
|
|
|
|
return iface;
|
|
}
|
|
#endif
|
|
|
|
static const QStringList initialListOfPlaces()
|
|
{
|
|
return QStringList{QDir::homePath(), QStringLiteral("trash:/")};
|
|
}
|
|
|
|
static const QStringList initialListOfShared()
|
|
{
|
|
return QStringList{QStringLiteral("remote:/"), QStringLiteral("/media/nfs")};
|
|
}
|
|
|
|
static const QStringList initialListOfRecent()
|
|
{
|
|
auto list = QStringList();
|
|
if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
|
|
list << QStringLiteral("recentlyused:/files");
|
|
list << QStringLiteral("recentlyused:/locations");
|
|
}
|
|
return list;
|
|
}
|
|
|
|
static const QStringList initialListOfDevices()
|
|
{
|
|
return QStringList{QStringLiteral("/foreign")};
|
|
}
|
|
|
|
static const QStringList initialListOfRemovableDevices()
|
|
{
|
|
return QStringList{QStringLiteral("/media/floppy0"), QStringLiteral("/media/XO-Y4"), QStringLiteral("/media/cdrom")};
|
|
}
|
|
|
|
static const QStringList initialListOfUrls()
|
|
{
|
|
return QStringList() << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices()
|
|
<< initialListOfRemovableDevices();
|
|
}
|
|
|
|
void KFilePlacesModelTest::testInitialList()
|
|
{
|
|
const QStringList urls = initialListOfUrls();
|
|
CHECK_PLACES_URLS(urls);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testAddingInLaterVersion_data()
|
|
{
|
|
QTest::addColumn<QByteArray>("contents");
|
|
QTest::addColumn<QStringList>("expectedUrls");
|
|
|
|
// Create a places file with only Home in it, and no version number
|
|
static const char contentsPart1[] =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
|
"<xbel xmlns:bookmark=\"http://www.freedesktop.org/standards/desktop-bookmarks\">\n";
|
|
|
|
static const char versionXml[] =
|
|
" <info>\n"
|
|
" <metadata owner=\"http://www.kde.org\">\n"
|
|
" <kde_places_version>2</kde_places_version>\n"
|
|
" </metadata>\n"
|
|
" </info>\n";
|
|
|
|
static const char contentsPart2[] =
|
|
" <bookmark href=\"trash:/\">\n"
|
|
" <title>Home</title>\n"
|
|
" <info>\n"
|
|
" <metadata owner=\"http://freedesktop.org\">\n"
|
|
" <bookmark:icon name=\"user-home\"/>\n"
|
|
" </metadata>\n"
|
|
" <metadata owner=\"http://www.kde.org\">\n"
|
|
" <ID>1481703882/0</ID>\n"
|
|
" <isSystemItem>true</isSystemItem>\n"
|
|
" </metadata>\n"
|
|
" </info>\n"
|
|
" </bookmark>\n"
|
|
"</xbel>";
|
|
|
|
// No version key: KFilePlacesModel will add the missing entries: home and remote
|
|
// Just not in the usual order
|
|
QStringList expectedWithReorder = initialListOfUrls();
|
|
expectedWithReorder.move(1, 0);
|
|
QTest::newRow("just_home_no_version") << (QByteArray(contentsPart1) + contentsPart2) << expectedWithReorder;
|
|
|
|
// Existing version key: home and remote were removed by the user, leave them out
|
|
QStringList expectedUrls{QStringLiteral("trash:/")};
|
|
expectedUrls << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
QVERIFY(expectedUrls.removeOne(QStringLiteral("remote:/")));
|
|
QTest::newRow("just_home_version_2") << (QByteArray(contentsPart1) + versionXml + contentsPart2) << expectedUrls;
|
|
}
|
|
|
|
void KFilePlacesModelTest::testAddingInLaterVersion()
|
|
{
|
|
QFETCH(QByteArray, contents);
|
|
QFETCH(QStringList, expectedUrls);
|
|
|
|
// Avoid interference
|
|
delete m_places;
|
|
delete m_places2;
|
|
QCoreApplication::processEvents();
|
|
|
|
KBookmarkManager mgr(bookmarksFile());
|
|
|
|
auto cleanupFunc = [this, &mgr]() {
|
|
QFile::remove(bookmarksFile());
|
|
// let KDirWatch process the deletion
|
|
QTRY_VERIFY(mgr.root().first().isNull());
|
|
createPlacesModels();
|
|
testInitialList();
|
|
};
|
|
struct Cleanup {
|
|
explicit Cleanup(const std::function<void()> &f)
|
|
: func(f)
|
|
{
|
|
}
|
|
~Cleanup()
|
|
{
|
|
func();
|
|
}
|
|
std::function<void()> func;
|
|
} cleanup(cleanupFunc);
|
|
|
|
QTest::qWait(1000); // for KDirWatch
|
|
QSignalSpy spy(&mgr, &KBookmarkManager::changed);
|
|
|
|
// WHEN
|
|
QFile file(bookmarksFile());
|
|
QVERIFY(file.open(QIODevice::WriteOnly));
|
|
file.write(contents);
|
|
file.close();
|
|
QVERIFY(spy.wait());
|
|
|
|
// THEN
|
|
KFilePlacesModel model;
|
|
QCoreApplication::processEvents(); // Devices have a delayed loading
|
|
|
|
if (placesUrls(&model) != expectedUrls) {
|
|
qDebug() << "Expected:" << expectedUrls;
|
|
qDebug() << "Got:" << placesUrls(&model);
|
|
QCOMPARE(placesUrls(&model), expectedUrls);
|
|
}
|
|
}
|
|
|
|
void KFilePlacesModelTest::testReparse()
|
|
{
|
|
// add item, and make sure m_places2 is synced
|
|
QSignalSpy rowsInsertedSpy(m_places2, &QAbstractItemModel::rowsInserted);
|
|
m_places->addPlace(QStringLiteral("foo"), QUrl::fromLocalFile(QStringLiteral("/foo")), QString(), QString());
|
|
if (rowsInsertedSpy.empty()) {
|
|
QVERIFY(rowsInsertedSpy.wait());
|
|
}
|
|
|
|
QStringList urls = initialListOfUrls();
|
|
// it will be added at the end of places section
|
|
urls.insert(2, QStringLiteral("/foo"));
|
|
CHECK_PLACES_URLS(urls);
|
|
|
|
// reparse the bookmark file
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
|
|
// check if they are the same
|
|
CHECK_PLACES_URLS(urls);
|
|
|
|
// try to remove item, and make sure m_places2 is synced
|
|
QSignalSpy rowsRemovedSpy(m_places2, &QAbstractItemModel::rowsRemoved);
|
|
m_places->removePlace(m_places->index(2, 0));
|
|
if (rowsRemovedSpy.empty()) {
|
|
QVERIFY(rowsRemovedSpy.wait());
|
|
}
|
|
|
|
urls = initialListOfUrls();
|
|
CHECK_PLACES_URLS(urls);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testInternalBookmarksHaveIds()
|
|
{
|
|
QSKIP("TODO testInternalBookmarksHaveIds doesn't pass FIXME");
|
|
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
KBookmarkGroup root = bookmarkManager.root();
|
|
|
|
// Verify every entry has an id or an udi
|
|
KBookmark bookmark = root.first();
|
|
while (!bookmark.isNull()) {
|
|
QVERIFY(!bookmark.metaDataItem(QStringLiteral("ID")).isEmpty() || !bookmark.metaDataItem(QStringLiteral("UDI")).isEmpty());
|
|
// It's mutually exclusive though
|
|
QVERIFY(bookmark.metaDataItem(QStringLiteral("ID")).isEmpty() || bookmark.metaDataItem(QStringLiteral("UDI")).isEmpty());
|
|
|
|
bookmark = root.next(bookmark);
|
|
}
|
|
|
|
// Verify that adding a bookmark behind its back the model gives it an id
|
|
// (in real life it requires the user to modify the file by hand,
|
|
// unlikely but better safe than sorry).
|
|
// It induces a small race condition which means several ids will be
|
|
// successively set on the same bookmark but no big deal since it won't
|
|
// break the system
|
|
KBookmark foo = root.addBookmark(QStringLiteral("Foo"), QUrl(QStringLiteral("file:/foo")), QStringLiteral("red-folder"));
|
|
QCOMPARE(foo.text(), QStringLiteral("Foo"));
|
|
QVERIFY(foo.metaDataItem(QStringLiteral("ID")).isEmpty());
|
|
bookmarkManager.emitChanged(root);
|
|
QCOMPARE(foo.text(), QStringLiteral("Foo"));
|
|
QVERIFY(!foo.metaDataItem(QStringLiteral("ID")).isEmpty());
|
|
|
|
// Verify that all the ids are different
|
|
bookmark = root.first();
|
|
QSet<QString> ids;
|
|
while (!bookmark.isNull()) {
|
|
QString id;
|
|
if (!bookmark.metaDataItem(QStringLiteral("UDI")).isEmpty()) {
|
|
id = bookmark.metaDataItem(QStringLiteral("UDI"));
|
|
} else {
|
|
id = bookmark.metaDataItem(QStringLiteral("ID"));
|
|
}
|
|
|
|
if (ids.contains(id)) {
|
|
// Some debugging help
|
|
qDebug() << "Bookmarks file:" << bookmarksFile() << "contains one (or more) duplicated bookmarks:";
|
|
QFile debugFile(bookmarksFile());
|
|
QVERIFY(debugFile.open(QIODevice::ReadOnly));
|
|
qDebug() << QString::fromUtf8(debugFile.readAll());
|
|
QVERIFY2(!ids.contains(id), qPrintable("Duplicated ID found: " + id));
|
|
}
|
|
ids << id;
|
|
bookmark = root.next(bookmark);
|
|
}
|
|
|
|
// Cleanup foo
|
|
root.deleteBookmark(foo);
|
|
bookmarkManager.emitChanged(root);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testHiding()
|
|
{
|
|
// Verify that nothing is hidden
|
|
for (int row = 0; row < m_places->rowCount(); ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
QVERIFY(!m_places->isHidden(index));
|
|
}
|
|
|
|
QModelIndex a = m_places->index(2, 0);
|
|
QModelIndex b = m_places->index(6, 0);
|
|
|
|
QList<QVariant> args;
|
|
QSignalSpy spy(m_places, &QAbstractItemModel::dataChanged);
|
|
|
|
// Verify that hidden is taken into account and is not global
|
|
m_places->setPlaceHidden(a, true);
|
|
QVERIFY(m_places->isHidden(a));
|
|
QVERIFY(m_places->data(a, KFilePlacesModel::HiddenRole).toBool());
|
|
QVERIFY(!m_places->isHidden(b));
|
|
QVERIFY(!m_places->data(b, KFilePlacesModel::HiddenRole).toBool());
|
|
QCOMPARE(spy.count(), 1);
|
|
args = spy.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), a);
|
|
QCOMPARE(args.at(1).toModelIndex(), a);
|
|
|
|
m_places->setPlaceHidden(b, true);
|
|
QVERIFY(m_places->isHidden(a));
|
|
QVERIFY(m_places->data(a, KFilePlacesModel::HiddenRole).toBool());
|
|
QVERIFY(m_places->isHidden(b));
|
|
QVERIFY(m_places->data(b, KFilePlacesModel::HiddenRole).toBool());
|
|
QCOMPARE(spy.count(), 1);
|
|
args = spy.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), b);
|
|
QCOMPARE(args.at(1).toModelIndex(), b);
|
|
|
|
m_places->setPlaceHidden(a, false);
|
|
m_places->setPlaceHidden(b, false);
|
|
QVERIFY(!m_places->isHidden(a));
|
|
QVERIFY(!m_places->data(a, KFilePlacesModel::HiddenRole).toBool());
|
|
QVERIFY(!m_places->isHidden(b));
|
|
QVERIFY(!m_places->data(b, KFilePlacesModel::HiddenRole).toBool());
|
|
QCOMPARE(spy.count(), 2);
|
|
args = spy.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), a);
|
|
QCOMPARE(args.at(1).toModelIndex(), a);
|
|
args = spy.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), b);
|
|
QCOMPARE(args.at(1).toModelIndex(), b);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testMove()
|
|
{
|
|
QSKIP("TODO testMove doesn't pass FIXME");
|
|
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_inserted(m_places, &QAbstractItemModel::rowsInserted);
|
|
QSignalSpy spy_removed(m_places, &QAbstractItemModel::rowsRemoved);
|
|
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
KBookmarkGroup root = bookmarkManager.root();
|
|
|
|
KBookmark system_home = m_places->bookmarkForIndex(m_places->index(0, 0));
|
|
|
|
// Trying move the root at the end of the list, should move it to the end of places section instead
|
|
// to keep it grouped
|
|
KBookmark last = root.first();
|
|
while (!root.next(last).isNull()) {
|
|
last = root.next(last);
|
|
}
|
|
root.moveBookmark(system_home, last);
|
|
bookmarkManager.emitChanged(root);
|
|
|
|
QStringList urls;
|
|
urls << QStringLiteral("trash:/") << QDir::homePath() << initialListOfShared() << initialListOfRecent() << initialListOfDevices()
|
|
<< initialListOfRemovableDevices();
|
|
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 0);
|
|
QCOMPARE(args.at(2).toInt(), 0);
|
|
|
|
// Move home at the beginning of the list (at its original place)
|
|
root.moveBookmark(system_home, KBookmark());
|
|
bookmarkManager.emitChanged(root);
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 0);
|
|
QCOMPARE(args.at(2).toInt(), 0);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testDragAndDrop()
|
|
{
|
|
QSKIP("TODO testDragAndDrop doesn't pass FIXME");
|
|
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_moved(m_places, &QAbstractItemModel::rowsMoved);
|
|
|
|
// Monitor rowsInserted() and rowsRemoved() to ensure they are never emitted:
|
|
// Moving with drag and drop is expected to emit rowsMoved()
|
|
QSignalSpy spy_inserted(m_places, &QAbstractItemModel::rowsInserted);
|
|
QSignalSpy spy_removed(m_places, &QAbstractItemModel::rowsRemoved);
|
|
|
|
// Move /home at the end of the places list
|
|
QModelIndexList indexes;
|
|
indexes << m_places->index(0, 0);
|
|
QMimeData *mimeData = m_places->mimeData(indexes);
|
|
QVERIFY(m_places->dropMimeData(mimeData, Qt::MoveAction, 2, 0, QModelIndex()));
|
|
|
|
QStringList urls;
|
|
urls << QStringLiteral("trash:/") << QDir::homePath() << initialListOfShared() << initialListOfRecent() << initialListOfDevices()
|
|
<< initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
QCOMPARE(spy_moved.count(), 1);
|
|
args = spy_moved.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 0);
|
|
QCOMPARE(args.at(2).toInt(), 0);
|
|
QCOMPARE(args.at(3).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(4).toInt(), 2);
|
|
|
|
// Move home back at the beginning of the list
|
|
indexes.clear();
|
|
indexes << m_places->index(1, 0);
|
|
mimeData = m_places->mimeData(indexes);
|
|
QVERIFY(m_places->dropMimeData(mimeData, Qt::MoveAction, 0, 0, QModelIndex()));
|
|
|
|
urls.clear();
|
|
urls << QDir::homePath() << QStringLiteral("trash:/") << initialListOfShared() << initialListOfRecent() << initialListOfDevices()
|
|
<< initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
QCOMPARE(spy_moved.count(), 1);
|
|
args = spy_moved.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
QCOMPARE(args.at(3).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(4).toInt(), 0);
|
|
|
|
// Dropping on an item is not allowed
|
|
indexes.clear();
|
|
indexes << m_places->index(4, 0);
|
|
mimeData = m_places->mimeData(indexes);
|
|
QVERIFY(!m_places->dropMimeData(mimeData, Qt::MoveAction, -1, 0, m_places->index(2, 0)));
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
QCOMPARE(spy_moved.count(), 0);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlacesLifecycle()
|
|
{
|
|
QSKIP("TODO testPlacesLifecycle doesn't pass FIXME");
|
|
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_inserted(m_places, &QAbstractItemModel::rowsInserted);
|
|
QSignalSpy spy_removed(m_places, &QAbstractItemModel::rowsRemoved);
|
|
QSignalSpy spy_changed(m_places, &QAbstractItemModel::dataChanged);
|
|
|
|
m_places->addPlace(QStringLiteral("Foo"), QUrl::fromLocalFile(QStringLiteral("/home/foo")));
|
|
|
|
QStringList urls;
|
|
urls << initialListOfPlaces() << QStringLiteral("/home/foo") << initialListOfShared() << initialListOfRecent() << initialListOfDevices()
|
|
<< initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 2);
|
|
QCOMPARE(args.at(2).toInt(), 2);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
KBookmarkGroup root = bookmarkManager.root();
|
|
KBookmark before_trash = m_places->bookmarkForIndex(m_places->index(0, 0));
|
|
KBookmark foo = m_places->bookmarkForIndex(m_places->index(2, 0));
|
|
|
|
root.moveBookmark(foo, before_trash);
|
|
bookmarkManager.emitChanged(root);
|
|
|
|
urls.clear();
|
|
urls << QDir::homePath() << QStringLiteral("/home/foo") << QStringLiteral("trash:/") << initialListOfShared() << initialListOfRecent()
|
|
<< initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 2);
|
|
QCOMPARE(args.at(2).toInt(), 2);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
|
|
m_places->editPlace(m_places->index(1, 0), QStringLiteral("Foo"), QUrl::fromLocalFile(QStringLiteral("/mnt/foo")));
|
|
|
|
urls.clear();
|
|
urls << QDir::homePath() << QStringLiteral("/mnt/foo") << QStringLiteral("trash:/") << initialListOfShared() << initialListOfRecent()
|
|
<< initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
QCOMPARE(spy_changed.count(), 1);
|
|
args = spy_changed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), m_places->index(1, 0));
|
|
QCOMPARE(args.at(1).toModelIndex(), m_places->index(1, 0));
|
|
|
|
foo = m_places->bookmarkForIndex(m_places->index(1, 0));
|
|
foo.setFullText(QStringLiteral("Bar"));
|
|
|
|
urls.clear();
|
|
urls << QDir::homePath() << QStringLiteral("/mnt/foo") << QStringLiteral("trash:/") << initialListOfShared() << initialListOfRecent()
|
|
<< initialListOfDevices() << initialListOfRemovableDevices();
|
|
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
QCOMPARE(spy_changed.count(), m_hasRecentlyUsedKio ? 11 : 9);
|
|
args = spy_changed[2];
|
|
QCOMPARE(args.at(0).toModelIndex(), m_places->index(2, 0));
|
|
QCOMPARE(args.at(1).toModelIndex(), m_places->index(2, 0));
|
|
spy_changed.clear();
|
|
|
|
m_places->removePlace(m_places->index(1, 0));
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
|
|
m_places->addPlace(QStringLiteral("Foo"), QUrl::fromLocalFile(QStringLiteral("/home/foo")), QString(), QString(), m_places->index(0, 0));
|
|
|
|
urls.clear();
|
|
urls << QDir::homePath() << QStringLiteral("/home/foo") << QStringLiteral("trash:/") << initialListOfShared() << initialListOfRecent()
|
|
<< initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), 1);
|
|
QCOMPARE(args.at(2).toInt(), 1);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
|
|
m_places->removePlace(m_places->index(1, 0));
|
|
}
|
|
|
|
void KFilePlacesModelTest::testDevicePlugging()
|
|
{
|
|
QSKIP("TODO testDevicePlugging doesn't pass FIXME");
|
|
|
|
#ifdef WITH_QTDBUS
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_inserted(m_places, &QAbstractItemModel::rowsInserted);
|
|
QSignalSpy spy_removed(m_places, &QAbstractItemModel::rowsRemoved);
|
|
|
|
fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
|
|
|
|
QStringList urls;
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << QStringLiteral("/media/floppy0")
|
|
<< QStringLiteral("/media/cdrom");
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
|
|
fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
|
|
// Move the device in the list, and check that it memorizes the position across plug/unplug
|
|
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
KBookmarkGroup root = bookmarkManager.root();
|
|
KBookmark before_floppy;
|
|
|
|
KBookmark device = root.first(); // The device we'll move is the 6th bookmark
|
|
const int count = m_hasRecentlyUsedKio ? 7 : 5;
|
|
for (int i = 0; i < count; i++) {
|
|
if (i == 2) {
|
|
// store item before to be able to move it back to original position
|
|
device = before_floppy = root.next(device);
|
|
} else {
|
|
device = root.next(device);
|
|
}
|
|
}
|
|
|
|
root.moveBookmark(device, before_floppy);
|
|
bookmarkManager.emitChanged(root);
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << QStringLiteral("/media/XO-Y4")
|
|
<< QStringLiteral("/media/floppy0") << QStringLiteral("/media/cdrom");
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
|
|
fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << QStringLiteral("/media/floppy0")
|
|
<< QStringLiteral("/media/cdrom");
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 0);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
|
|
fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << QStringLiteral("/media/XO-Y4")
|
|
<< QStringLiteral("/media/floppy0") << QStringLiteral("/media/cdrom");
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
QCOMPARE(spy_removed.count(), 0);
|
|
|
|
KBookmark seventh = root.first();
|
|
for (int i = 0; i < count; i++) {
|
|
seventh = root.next(seventh);
|
|
}
|
|
root.moveBookmark(device, seventh);
|
|
bookmarkManager.emitChanged(root);
|
|
|
|
urls.clear();
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QCOMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(spy_removed.count(), 1);
|
|
args = spy_removed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 7 : 5);
|
|
#endif
|
|
}
|
|
|
|
void KFilePlacesModelTest::testDeviceSetupTeardown()
|
|
{
|
|
#ifdef WITH_QTDBUS
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_changed(m_places, &QAbstractItemModel::dataChanged);
|
|
|
|
fakeDevice(QStringLiteral("/org/kde/solid/fakehw/volume_part1_size_993284096/StorageAccess"))->call(QStringLiteral("teardown"));
|
|
|
|
QCOMPARE(spy_changed.count(), 1);
|
|
args = spy_changed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex().row(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(1).toModelIndex().row(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
|
|
fakeDevice(QStringLiteral("/org/kde/solid/fakehw/volume_part1_size_993284096/StorageAccess"))->call(QStringLiteral("setup"));
|
|
|
|
QCOMPARE(spy_changed.count(), 1);
|
|
args = spy_changed.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex().row(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
QCOMPARE(args.at(1).toModelIndex().row(), m_hasRecentlyUsedKio ? 8 : 6);
|
|
#endif
|
|
}
|
|
|
|
void KFilePlacesModelTest::testEnableBaloo()
|
|
{
|
|
KConfig config(QStringLiteral("baloofilerc"));
|
|
KConfigGroup basicSettings = config.group(QStringLiteral("Basic Settings"));
|
|
basicSettings.writeEntry("Indexing-Enabled", true);
|
|
config.sync();
|
|
|
|
KFilePlacesModel places_with_baloo;
|
|
QStringList urls;
|
|
for (int row = 0; row < places_with_baloo.rowCount(); ++row) {
|
|
QModelIndex index = places_with_baloo.index(row, 0);
|
|
urls << places_with_baloo.url(index).toDisplayString(QUrl::PreferLocalFile);
|
|
}
|
|
|
|
if (m_hasRecentlyUsedKio) {
|
|
QVERIFY(urls.contains("recentlyused:/files"));
|
|
QVERIFY(urls.contains("recentlyused:/locations"));
|
|
}
|
|
}
|
|
|
|
void KFilePlacesModelTest::testRemoteUrls_data()
|
|
{
|
|
QTest::addColumn<QUrl>("url");
|
|
QTest::addColumn<int>("expectedRow");
|
|
QTest::addColumn<QString>("expectedGroup");
|
|
|
|
QTest::newRow("Ftp") << QUrl(QStringLiteral("ftp://192.168.1.1/ftp")) << 4 << QStringLiteral("Remote");
|
|
QTest::newRow("Samba") << QUrl(QStringLiteral("smb://192.168.1.1/share")) << 4 << QStringLiteral("Remote");
|
|
QTest::newRow("Sftp") << QUrl(QStringLiteral("sftp://192.168.1.1/share")) << 4 << QStringLiteral("Remote");
|
|
QTest::newRow("Fish") << QUrl(QStringLiteral("fish://192.168.1.1/share")) << 4 << QStringLiteral("Remote");
|
|
QTest::newRow("Webdav") << QUrl(QStringLiteral("webdav://192.168.1.1/share")) << 4 << QStringLiteral("Remote");
|
|
}
|
|
|
|
void KFilePlacesModelTest::testRemoteUrls()
|
|
{
|
|
QSKIP("TODO testRemoteUrls doesn't pass FIXME");
|
|
|
|
QFETCH(QUrl, url);
|
|
QFETCH(int, expectedRow);
|
|
QFETCH(QString, expectedGroup);
|
|
|
|
QList<QVariant> args;
|
|
QSignalSpy spy_inserted(m_places, &QAbstractItemModel::rowsInserted);
|
|
|
|
// insert a new network url
|
|
m_places->addPlace(QStringLiteral("My Shared"), url, QString(), QString(), QModelIndex());
|
|
|
|
// check if url list is correct after insertion
|
|
QStringList urls;
|
|
urls << QDir::homePath() << QStringLiteral("trash:/") // places
|
|
<< QStringLiteral("remote:/") << QStringLiteral("/media/nfs") << url.toString() << initialListOfRecent() << QStringLiteral("/foreign")
|
|
<< QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
|
|
CHECK_PLACES_URLS(urls);
|
|
|
|
// check if the new url was inserted in the right position (end of "Remote" section)
|
|
QTRY_COMPARE(spy_inserted.count(), 1);
|
|
args = spy_inserted.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex(), QModelIndex());
|
|
QCOMPARE(args.at(1).toInt(), expectedRow);
|
|
QCOMPARE(args.at(2).toInt(), expectedRow);
|
|
|
|
// check if the new url has the right group "Remote"
|
|
const QModelIndex index = m_places->index(expectedRow, 0);
|
|
QCOMPARE(index.data(KFilePlacesModel::GroupRole).toString(), expectedGroup);
|
|
|
|
m_places->removePlace(index);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testRefresh()
|
|
{
|
|
QSKIP("TODO testRefresh doesn't pass FIXME");
|
|
|
|
KBookmarkManager bookmarkManager(bookmarksFile());
|
|
KBookmarkGroup root = bookmarkManager.root();
|
|
KBookmark homePlace = root.first();
|
|
const QModelIndex homePlaceIndex = m_places->index(0, 0);
|
|
|
|
QCOMPARE(m_places->text(homePlaceIndex), homePlace.fullText());
|
|
|
|
// modify bookmark
|
|
homePlace.setFullText("Test change the text");
|
|
QVERIFY(m_places->text(homePlaceIndex) != homePlace.fullText());
|
|
|
|
// reload bookmark data
|
|
m_places->refresh();
|
|
QCOMPARE(m_places->text(homePlaceIndex), homePlace.fullText());
|
|
}
|
|
|
|
void KFilePlacesModelTest::testConvertedUrl_data()
|
|
{
|
|
QTest::addColumn<QUrl>("url");
|
|
QTest::addColumn<QUrl>("expectedUrl");
|
|
|
|
// places
|
|
QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QUrl::fromLocalFile(QDir::homePath());
|
|
|
|
// baloo -search
|
|
QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QUrl("baloosearch:/documents");
|
|
|
|
QTest::newRow("Baloo - Unknown Type") << QUrl("search:/unknown") << QUrl("search:/unknown");
|
|
|
|
// baloo - timeline
|
|
const QDate lastMonthDate = QDate::currentDate().addMonths(-1);
|
|
QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth")
|
|
<< QUrl(QString("timeline:/%1-%2").arg(lastMonthDate.year()).arg(lastMonthDate.month(), 2, 10, QLatin1Char('0')));
|
|
|
|
// devices
|
|
QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QUrl("file:///media/floppy0");
|
|
}
|
|
|
|
void KFilePlacesModelTest::testConvertedUrl()
|
|
{
|
|
QFETCH(QUrl, url);
|
|
QFETCH(QUrl, expectedUrl);
|
|
|
|
const QUrl convertedUrl = KFilePlacesModel::convertedUrl(url);
|
|
|
|
QCOMPARE(convertedUrl.scheme(), expectedUrl.scheme());
|
|
QCOMPARE(convertedUrl.path(), expectedUrl.path());
|
|
QCOMPARE(convertedUrl, expectedUrl);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testBookmarkObject()
|
|
{
|
|
// make sure that all items return a valid bookmark
|
|
for (int row = 0; row < m_places->rowCount(); row++) {
|
|
const QModelIndex index = m_places->index(row, 0);
|
|
const KBookmark bookmark = m_places->bookmarkForIndex(index);
|
|
QVERIFY(!bookmark.isNull());
|
|
}
|
|
}
|
|
|
|
void KFilePlacesModelTest::testDataChangedSignal()
|
|
{
|
|
QSignalSpy dataChangedSpy(m_places, &KFilePlacesModel::dataChanged);
|
|
|
|
const QModelIndex index = m_places->index(1, 0);
|
|
const KBookmark bookmark = m_places->bookmarkForIndex(index);
|
|
|
|
// call function with the same data
|
|
m_places->editPlace(index, bookmark.fullText(), bookmark.url(), bookmark.icon(), bookmark.metaDataItem(QStringLiteral("OnlyInApp")));
|
|
QCOMPARE(dataChangedSpy.count(), 0);
|
|
|
|
// call function with different data
|
|
const QString originalText = bookmark.fullText();
|
|
m_places->editPlace(index, QStringLiteral("My text"), bookmark.url(), bookmark.icon(), bookmark.metaDataItem(QStringLiteral("OnlyInApp")));
|
|
QCOMPARE(dataChangedSpy.count(), 1);
|
|
QList<QVariant> args = dataChangedSpy.takeFirst();
|
|
QCOMPARE(args.at(0).toModelIndex().row(), 1);
|
|
QCOMPARE(args.at(0).toModelIndex().column(), 0);
|
|
QCOMPARE(args.at(1).toModelIndex().row(), 1);
|
|
QCOMPARE(args.at(1).toModelIndex().column(), 0);
|
|
QCOMPARE(m_places->text(index), QStringLiteral("My text"));
|
|
|
|
// restore original value
|
|
dataChangedSpy.clear();
|
|
m_places->editPlace(index, originalText, bookmark.url(), bookmark.icon(), bookmark.metaDataItem(QStringLiteral("OnlyInApp")));
|
|
QCOMPARE(dataChangedSpy.count(), 1);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testIconRole_data()
|
|
{
|
|
QTest::addColumn<QModelIndex>("index");
|
|
QTest::addColumn<QString>("expectedIconName");
|
|
|
|
// places
|
|
int index = 0;
|
|
QTest::newRow("Places - Home") << m_places->index(index++, 0) << QStringLiteral("user-home");
|
|
QTest::newRow("Places - Trash") << m_places->index(index++, 0) << QStringLiteral("user-trash");
|
|
|
|
QTest::newRow("Remote - Network") << m_places->index(index++, 0) << QStringLiteral("folder-network");
|
|
QTest::newRow("Devices - Nfs") << m_places->index(index++, 0) << QStringLiteral("hwinfo");
|
|
if (m_hasRecentlyUsedKio) {
|
|
QTest::newRow("Recent Files") << m_places->index(index++, 0) << QStringLiteral("document-open-recent");
|
|
QTest::newRow("Recent Locations") << m_places->index(index++, 0) << QStringLiteral("folder-open-recent");
|
|
}
|
|
QTest::newRow("Devices - foreign") << m_places->index(index++, 0) << QStringLiteral("blockdevice");
|
|
QTest::newRow("Devices - Floppy") << m_places->index(index++, 0) << QStringLiteral("blockdevice");
|
|
QTest::newRow("Devices - cdrom") << m_places->index(index++, 0) << QStringLiteral("blockdevice");
|
|
}
|
|
|
|
void KFilePlacesModelTest::testIconRole()
|
|
{
|
|
QSKIP("TODO testIconRole doesn't pass FIXME");
|
|
|
|
QFETCH(QModelIndex, index);
|
|
QFETCH(QString, expectedIconName);
|
|
|
|
QVERIFY(index.data(KFilePlacesModel::IconNameRole).toString().startsWith(expectedIconName));
|
|
}
|
|
|
|
void KFilePlacesModelTest::testMoveFunction()
|
|
{
|
|
QSKIP("TODO testMoveFunction doesn't pass FIXME");
|
|
|
|
QList<QVariant> args;
|
|
QStringList urls = initialListOfUrls();
|
|
QSignalSpy rowsMoved(m_places, &KFilePlacesModel::rowsMoved);
|
|
|
|
// move item 0 to pos 1
|
|
QVERIFY(m_places->movePlace(0, 2));
|
|
urls.move(0, 1);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), 0); // start
|
|
QCOMPARE(args.at(2).toInt(), 0); // end
|
|
QCOMPARE(args.at(4).toInt(), 2); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
// move it back
|
|
QVERIFY(m_places->movePlace(1, 0));
|
|
urls.move(1, 0);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), 1); // start
|
|
QCOMPARE(args.at(2).toInt(), 1); // end
|
|
QCOMPARE(args.at(4).toInt(), 0); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
// target position is greater than model rows
|
|
// will move to the end of the first group
|
|
QVERIFY(m_places->movePlace(0, 20));
|
|
urls.move(0, 1);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), 0); // start
|
|
QCOMPARE(args.at(2).toInt(), 0); // end
|
|
QCOMPARE(args.at(4).toInt(), 2); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
// move it back
|
|
QVERIFY(m_places->movePlace(1, 0));
|
|
urls.move(1, 0);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), 1); // start
|
|
QCOMPARE(args.at(2).toInt(), 1); // end
|
|
QCOMPARE(args.at(4).toInt(), 0); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
QVERIFY(m_places->movePlace(m_hasRecentlyUsedKio ? 8 : 7, m_hasRecentlyUsedKio ? 6 : 5));
|
|
urls.move(m_hasRecentlyUsedKio ? 8 : 7, m_hasRecentlyUsedKio ? 6 : 5);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 8 : 7); // start
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 8 : 7); // end
|
|
QCOMPARE(args.at(4).toInt(), m_hasRecentlyUsedKio ? 6 : 5); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
// move it back
|
|
QVERIFY(m_places->movePlace(m_hasRecentlyUsedKio ? 6 : 5, m_hasRecentlyUsedKio ? 9 : 8));
|
|
urls.move(m_hasRecentlyUsedKio ? 6 : 5, m_hasRecentlyUsedKio ? 8 : 7);
|
|
QTRY_COMPARE(rowsMoved.count(), 1);
|
|
args = rowsMoved.takeFirst();
|
|
QCOMPARE(args.at(1).toInt(), m_hasRecentlyUsedKio ? 6 : 5); // start
|
|
QCOMPARE(args.at(2).toInt(), m_hasRecentlyUsedKio ? 6 : 5); // end
|
|
QCOMPARE(args.at(4).toInt(), m_hasRecentlyUsedKio ? 9 : 8); // row (destination)
|
|
QCOMPARE(placesUrls(), urls);
|
|
rowsMoved.clear();
|
|
|
|
// use a invalid start position
|
|
QVERIFY(!m_places->movePlace(100, 20));
|
|
QCOMPARE(rowsMoved.count(), 0);
|
|
|
|
// use same start and target position
|
|
QVERIFY(!m_places->movePlace(1, 1));
|
|
QCOMPARE(rowsMoved.count(), 0);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHidden()
|
|
{
|
|
QSKIP("TODO testPlaceGroupHidden doesn't pass FIXME");
|
|
|
|
// GIVEN
|
|
QCOMPARE(m_places->hiddenCount(), 0);
|
|
|
|
QStringList urls;
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
QList<QModelIndex> indexesHidden;
|
|
|
|
// WHEN
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, true);
|
|
|
|
// THEN
|
|
for (int row = 0; row < m_places->rowCount(); ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
if (m_places->groupType(index) == KFilePlacesModel::PlacesType) {
|
|
QVERIFY(m_places->isHidden(index));
|
|
indexesHidden << index;
|
|
}
|
|
}
|
|
QCOMPARE(indexesHidden.count(), initialListOfPlaces().size());
|
|
QCOMPARE(m_places->hiddenCount(), indexesHidden.size());
|
|
|
|
// and GIVEN
|
|
QList<QModelIndex> indexesShown;
|
|
|
|
// WHEN
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, false);
|
|
|
|
// THEN
|
|
for (int row = 0; row < m_places->rowCount(); ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
if (m_places->groupType(index) == KFilePlacesModel::PlacesType) {
|
|
QVERIFY(!m_places->isHidden(index));
|
|
indexesShown << index;
|
|
}
|
|
}
|
|
QCOMPARE(m_places->hiddenCount(), 0);
|
|
QCOMPARE(indexesShown.count(), initialListOfPlaces().size());
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHiddenVsPlaceChildShown()
|
|
{
|
|
// GIVEN
|
|
for (int row = 0; row < m_places->rowCount(); ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
QVERIFY(!m_places->isHidden(index));
|
|
}
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, true);
|
|
|
|
QModelIndex firstIndex = m_places->index(0, 0);
|
|
const int amountOfPlaces = initialListOfPlaces().size();
|
|
for (int row = 0; row < amountOfPlaces; ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
QVERIFY(m_places->isHidden(index));
|
|
}
|
|
// WHEN
|
|
m_places->setPlaceHidden(firstIndex, false);
|
|
|
|
// THEN
|
|
QVERIFY(m_places->isHidden(firstIndex)); // a child cannot show against its parent state
|
|
|
|
// leaving in a clean state
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, false);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHiddenAndShownWithHiddenChild()
|
|
{
|
|
QSKIP("TODO testPlaceGroupHiddenAndShownWithHiddenChild doesn't pass FIXME");
|
|
|
|
// GIVEN
|
|
QCOMPARE(m_places->hiddenCount(), 0);
|
|
|
|
QStringList urls;
|
|
urls << initialListOfPlaces() << initialListOfShared() << initialListOfRecent() << initialListOfDevices() << initialListOfRemovableDevices();
|
|
CHECK_PLACES_URLS(urls);
|
|
|
|
QModelIndex firstIndexHidden = m_places->index(0, 0);
|
|
m_places->setPlaceHidden(firstIndexHidden, true); // first place index is hidden within an hidden parent
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, true);
|
|
QCOMPARE(m_places->hiddenCount(), initialListOfPlaces().size());
|
|
|
|
// WHEN
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, false);
|
|
|
|
// THEN
|
|
QList<QModelIndex> indexesShown;
|
|
for (int row = 0; row < m_places->rowCount(); ++row) {
|
|
QModelIndex index = m_places->index(row, 0);
|
|
if (index == firstIndexHidden) {
|
|
QVERIFY(m_places->isHidden(firstIndexHidden));
|
|
continue;
|
|
}
|
|
if (m_places->groupType(index) == KFilePlacesModel::PlacesType) {
|
|
QVERIFY(!m_places->isHidden(index));
|
|
indexesShown << index;
|
|
}
|
|
}
|
|
QCOMPARE(m_places->hiddenCount(), 1);
|
|
QCOMPARE(indexesShown.count(), initialListOfPlaces().size() - 1 /*first child remains hidden*/);
|
|
|
|
// leaving in a clean state
|
|
m_places->setPlaceHidden(firstIndexHidden, false);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHiddenGroupIndexesIntegrity()
|
|
{
|
|
QSKIP("TODO testPlaceGroupHiddenGroupIndexesIntegrity doesn't pass FIXME");
|
|
|
|
// GIVEN
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, true);
|
|
QVERIFY(m_places->groupIndexes(KFilePlacesModel::UnknownType).isEmpty());
|
|
QVERIFY(m_places->isGroupHidden(KFilePlacesModel::PlacesType));
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::PlacesType).count(), initialListOfPlaces().count());
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::RecentlySavedType).count(), m_hasRecentlyUsedKio ? 2 : 0);
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::SearchForType).count(), 0);
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::DevicesType).count(), initialListOfDevices().count());
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::RemovableDevicesType).count(), initialListOfRemovableDevices().count());
|
|
|
|
// WHEN
|
|
m_places->setGroupHidden(KFilePlacesModel::PlacesType, false);
|
|
|
|
// THEN
|
|
// Make sure that hidden place group doesn't change model
|
|
QVERIFY(!m_places->isGroupHidden(KFilePlacesModel::PlacesType));
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::PlacesType).count(), initialListOfPlaces().count());
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::RecentlySavedType).count(), m_hasRecentlyUsedKio ? 2 : 0);
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::SearchForType).count(), 0);
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::DevicesType).count(), initialListOfDevices().count());
|
|
QCOMPARE(m_places->groupIndexes(KFilePlacesModel::RemovableDevicesType).count(), initialListOfRemovableDevices().count());
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHiddenSignal()
|
|
{
|
|
QSignalSpy groupHiddenSignal(m_places, &KFilePlacesModel::groupHiddenChanged);
|
|
m_places->setGroupHidden(KFilePlacesModel::SearchForType, true);
|
|
|
|
// hide SearchForType group
|
|
QTRY_COMPARE(groupHiddenSignal.count(), 1);
|
|
QList<QVariant> args = groupHiddenSignal.takeFirst();
|
|
QCOMPARE(args.at(0).toInt(), static_cast<int>(KFilePlacesModel::SearchForType));
|
|
QCOMPARE(args.at(1).toBool(), true);
|
|
groupHiddenSignal.clear();
|
|
|
|
// try hide SearchForType which is already hidden
|
|
m_places->setGroupHidden(KFilePlacesModel::SearchForType, true);
|
|
QCOMPARE(groupHiddenSignal.count(), 0);
|
|
|
|
// show SearchForType group
|
|
m_places->setGroupHidden(KFilePlacesModel::SearchForType, false);
|
|
QTRY_COMPARE(groupHiddenSignal.count(), 1);
|
|
args = groupHiddenSignal.takeFirst();
|
|
QCOMPARE(args.at(0).toInt(), static_cast<int>(KFilePlacesModel::SearchForType));
|
|
QCOMPARE(args.at(1).toBool(), false);
|
|
}
|
|
|
|
void KFilePlacesModelTest::testPlaceGroupHiddenRole()
|
|
{
|
|
QSKIP("TODO testPlaceGroupHiddenRole doesn't pass FIXME");
|
|
|
|
// on startup all groups are visible
|
|
for (int r = 0, rMax = m_places->rowCount(); r < rMax; r++) {
|
|
const QModelIndex index = m_places->index(r, 0);
|
|
QCOMPARE(index.data(KFilePlacesModel::GroupHiddenRole).toBool(), false);
|
|
}
|
|
|
|
// set SearchFor group hidden
|
|
m_places->setGroupHidden(KFilePlacesModel::SearchForType, true);
|
|
for (auto groupType : {KFilePlacesModel::PlacesType,
|
|
KFilePlacesModel::RemoteType,
|
|
KFilePlacesModel::RecentlySavedType,
|
|
KFilePlacesModel::SearchForType,
|
|
KFilePlacesModel::DevicesType,
|
|
KFilePlacesModel::RemovableDevicesType}) {
|
|
const bool groupShouldBeHidden = (groupType == KFilePlacesModel::SearchForType);
|
|
const QModelIndexList indexes = m_places->groupIndexes(groupType);
|
|
for (const QModelIndex &index : indexes) {
|
|
QCOMPARE(index.data(KFilePlacesModel::GroupHiddenRole).toBool(), groupShouldBeHidden);
|
|
}
|
|
}
|
|
|
|
// set SearchFor group visible again
|
|
m_places->setGroupHidden(KFilePlacesModel::SearchForType, false);
|
|
for (int r = 0, rMax = m_places->rowCount(); r < rMax; r++) {
|
|
const QModelIndex index = m_places->index(r, 0);
|
|
QCOMPARE(index.data(KFilePlacesModel::GroupHiddenRole).toBool(), false);
|
|
}
|
|
}
|
|
|
|
void KFilePlacesModelTest::testSupportedSchemes()
|
|
{
|
|
QSKIP("TODO testSupportedSchemes doesn't pass FIXME");
|
|
|
|
QCoreApplication::processEvents(); // support running this test on its own
|
|
|
|
QCOMPARE(m_places->supportedSchemes(), QStringList());
|
|
QCOMPARE(placesUrls(), initialListOfUrls());
|
|
m_places->setSupportedSchemes({"trash"});
|
|
QCOMPARE(m_places->supportedSchemes(), QStringList("trash"));
|
|
QCOMPARE(placesUrls(), QStringList("trash:/"));
|
|
m_places->setSupportedSchemes({});
|
|
QCOMPARE(m_places->supportedSchemes(), QStringList());
|
|
QCOMPARE(placesUrls(), initialListOfUrls());
|
|
}
|
|
|
|
QTEST_MAIN(KFilePlacesModelTest)
|
|
|
|
#include "kfileplacesmodeltest.moc"
|