2 * SPDX-FileCopyrightText: 2017 Renato Araujo Oliveira <renato.araujo@kdab.com>
4 * SPDX-License-Identifier: GPL-2.0-or-later
9 #include <QStandardPaths>
11 #include <QDBusInterface>
13 #include <KBookmarkManager>
15 #include <KConfigGroup>
17 #include <KFilePlacesModel>
18 #include <KProtocolInfo>
20 #include "dolphin_generalsettings.h"
21 #include "panels/places/placesitemmodel.h"
22 #include "panels/places/placesitem.h"
23 #include "views/viewproperties.h"
25 Q_DECLARE_METATYPE(KItemRangeList
)
26 Q_DECLARE_METATYPE(KItemRange
)
28 static QString
bookmarksFile()
30 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + "/user-places.xbel";
33 class PlacesItemModelTest
: public QObject
42 void cleanupTestCase();
46 void testDeletePlace();
47 void testPlaceItem_data();
49 void testTearDownDevice();
50 void testDefaultViewProperties_data();
51 void testDefaultViewProperties();
54 void testSystemItems();
55 void testEditBookmark();
56 void testEditAfterCreation();
57 void testEditMetadata();
59 void testIcons_data();
61 void testDragAndDrop();
62 void testHideDevices();
63 void testDuplicatedEntries();
64 void renameAfterCreation();
67 PlacesItemModel
* m_model
;
68 QSet
<int> m_tobeRemoved
;
69 QMap
<QString
, QDBusInterface
*> m_interfacesMap
;
70 int m_expectedModelCount
= qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused")) ? 14 : 12;
71 bool m_hasDesktopFolder
= false;
72 bool m_hasDocumentsFolder
= false;
73 bool m_hasDownloadsFolder
= false;
75 void setBalooEnabled(bool enabled
);
76 int indexOf(const QUrl
&url
);
77 QDBusInterface
*fakeManager();
78 QDBusInterface
*fakeDevice(const QString
&udi
);
79 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
80 QStringList
initialUrls() const;
81 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
82 void schedulePlaceRemoval(int index
);
83 void cancelPlaceRemoval(int index
);
84 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
85 QTemporaryDir m_tempHomeDir
;
88 #define CHECK_PLACES_URLS(urls) \
90 QStringList places = placesUrls(); \
91 if (places != urls) { \
92 qWarning() << "Expected:" << urls; \
93 qWarning() << "Got:" << places; \
94 QCOMPARE(places, urls); \
98 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
100 KConfig
config(QStringLiteral("baloofilerc"));
101 KConfigGroup basicSettings
= config
.group("Basic Settings");
102 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
106 int PlacesItemModelTest::indexOf(const QUrl
&url
)
108 for (int r
= 0; r
< m_model
->count(); r
++) {
109 if (m_model
->placesItem(r
)->url() == url
) {
116 QDBusInterface
*PlacesItemModelTest::fakeManager()
118 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
121 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
123 if (m_interfacesMap
.contains(udi
)) {
124 return m_interfacesMap
[udi
];
127 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
128 m_interfacesMap
[udi
] = iface
;
133 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
140 for (int row
= 0; row
< model
->count(); ++row
) {
141 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
146 QStringList
PlacesItemModelTest::initialUrls() const
148 static QStringList urls
;
149 if (urls
.isEmpty()) {
150 urls
<< QDir::homePath();
152 if (m_hasDesktopFolder
) {
153 urls
<< QDir::homePath() + QStringLiteral("/Desktop");
156 if (m_hasDocumentsFolder
) {
157 urls
<< QDir::homePath() + QStringLiteral("/Documents");
160 if (m_hasDownloadsFolder
) {
161 urls
<< QDir::homePath() + QStringLiteral("/Downloads");
164 urls
<< QStringLiteral("trash:/")
165 << QStringLiteral("remote:/")
166 << QStringLiteral("/media/nfs");
168 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
169 urls
<< QStringLiteral("recentlyused:/files");
170 urls
<< QStringLiteral("recentlyused:/locations");
173 urls
<< QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
174 << QStringLiteral("/foreign")
175 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
180 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
182 m_model
->createPlacesItem(text
, url
, icon
);
185 void PlacesItemModelTest::schedulePlaceRemoval(int index
)
187 m_tobeRemoved
.insert(index
);
190 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
192 m_tobeRemoved
.remove(index
);
195 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
198 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
201 for (int index
: indexes
) {
202 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
203 if (itemUrl
.isValid()) {
209 QMimeData
* mimeData
= new QMimeData();
210 mimeData
->setUrls(urls
);
211 // copied from PlacesItemModel::internalMimeType()
212 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
213 QString::number((qptrdiff
)m_model
);
214 mimeData
->setData(internalMimeType
, itemData
);
218 void PlacesItemModelTest::init()
220 m_model
= new PlacesItemModel();
221 // WORKAROUND: need to wait for bookmark to load
223 QCOMPARE(m_model
->count(), m_expectedModelCount
);
226 void PlacesItemModelTest::cleanup()
228 const auto tobeRemoved
= m_tobeRemoved
;
229 for (const int i
: tobeRemoved
) {
230 int before
= m_model
->count();
231 m_model
->deleteItem(i
);
232 QTRY_COMPARE(m_model
->count(), before
- 1);
234 m_tobeRemoved
.clear();
239 void PlacesItemModelTest::initTestCase()
241 QVERIFY(m_tempHomeDir
.isValid());
242 QVERIFY(qputenv("HOME", m_tempHomeDir
.path().toUtf8()));
243 QVERIFY(qputenv("KDE_FORK_SLAVES", "yes"));
245 QStandardPaths::setTestModeEnabled(true);
247 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
248 QVERIFY(!fakeHw
.isEmpty());
249 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
251 setBalooEnabled(true);
252 const QString bookmarsFileName
= bookmarksFile();
253 if (QFileInfo::exists(bookmarsFileName
)) {
254 // Ensure we'll have a clean bookmark file to start
255 QVERIFY(QFile::remove(bookmarsFileName
));
258 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation
)).exists()) {
259 m_hasDesktopFolder
= true;
260 m_expectedModelCount
++;
263 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation
)).exists()) {
264 m_hasDocumentsFolder
= true;
265 m_expectedModelCount
++;
268 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation
)).exists()) {
269 m_hasDownloadsFolder
= true;
270 m_expectedModelCount
++;
273 qRegisterMetaType
<KItemRangeList
>();
274 qRegisterMetaType
<KItemRange
>();
277 void PlacesItemModelTest::cleanupTestCase()
279 qDeleteAll(m_interfacesMap
);
280 QFile::remove(bookmarksFile());
283 void PlacesItemModelTest::testModelSort()
285 CHECK_PLACES_URLS(initialUrls());
288 void PlacesItemModelTest::testGroups()
290 const auto groups
= m_model
->groups();
291 int expectedRemoteIndex
= 2;
292 if (m_hasDesktopFolder
) {
293 expectedRemoteIndex
++;
295 if (m_hasDocumentsFolder
) {
296 expectedRemoteIndex
++;
298 if (m_hasDownloadsFolder
) {
299 expectedRemoteIndex
++;
302 QCOMPARE(groups
.size(), 6);
304 QCOMPARE(groups
.at(0).first
, 0);
305 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
307 QCOMPARE(groups
.at(1).first
, expectedRemoteIndex
);
308 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
310 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
311 expectedRemoteIndex
+= 2;
314 QCOMPARE(groups
.at(3).first
, expectedRemoteIndex
+ 2);
315 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
317 QCOMPARE(groups
.at(4).first
, expectedRemoteIndex
+ 6);
318 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
320 QCOMPARE(groups
.at(5).first
, expectedRemoteIndex
+ 7);
321 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
324 void PlacesItemModelTest::testPlaceItem_data()
326 QTest::addColumn
<QUrl
>("url");
327 QTest::addColumn
<bool>("expectedIsHidden");
328 QTest::addColumn
<bool>("expectedIsSystemItem");
329 QTest::addColumn
<QString
>("expectedGroup");
330 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
333 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
336 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
339 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
342 void PlacesItemModelTest::testPlaceItem()
345 QFETCH(bool, expectedIsHidden
);
346 QFETCH(bool, expectedIsSystemItem
);
347 QFETCH(QString
, expectedGroup
);
348 QFETCH(bool, expectedStorageSetupNeeded
);
350 const int index
= indexOf(url
);
351 PlacesItem
*item
= m_model
->placesItem(index
);
352 QCOMPARE(item
->url(), url
);
353 QCOMPARE(item
->isHidden(), expectedIsHidden
);
354 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
355 QCOMPARE(item
->group(), expectedGroup
);
356 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
359 void PlacesItemModelTest::testDeletePlace()
361 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
362 QStringList urls
= initialUrls();
363 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
364 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
366 PlacesItemModel
*model
= new PlacesItemModel();
368 int tempDirIndex
= 2;
369 if (m_hasDesktopFolder
) {
372 if (m_hasDocumentsFolder
) {
375 if (m_hasDownloadsFolder
) {
379 // create a new place
380 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
381 urls
.insert(tempDirIndex
, tempUrl
.toLocalFile());
383 // check if the new entry was created
384 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
385 CHECK_PLACES_URLS(urls
);
386 QTRY_COMPARE(model
->count(), m_model
->count());
389 m_model
->deleteItem(tempDirIndex
);
391 // make sure that the new item is removed
392 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
393 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
394 CHECK_PLACES_URLS(initialUrls());
395 QTRY_COMPARE(model
->count(), m_model
->count());
398 void PlacesItemModelTest::testTearDownDevice()
400 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
401 int index
= indexOf(mediaUrl
);
402 QVERIFY(index
!= -1);
404 auto ejectAction
= m_model
->ejectAction(index
);
405 QVERIFY(!ejectAction
);
407 auto teardownAction
= m_model
->teardownAction(index
);
408 QVERIFY(teardownAction
);
410 QCOMPARE(m_model
->count(), m_expectedModelCount
);
412 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
413 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
414 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
- 1);
415 QCOMPARE(spyItemsRemoved
.count(), 1);
416 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
417 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
418 QCOMPARE(removedRange
.size(), 1);
419 QCOMPARE(removedRange
.first().index
, index
);
420 QCOMPARE(removedRange
.first().count
, 1);
422 QCOMPARE(indexOf(mediaUrl
), -1);
424 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
425 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
426 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
427 QCOMPARE(spyItemsInserted
.count(), 1);
428 index
= indexOf(mediaUrl
);
430 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
431 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
432 QCOMPARE(insertedRange
.size(), 1);
433 QCOMPARE(insertedRange
.first().index
, index
);
434 QCOMPARE(insertedRange
.first().count
, 1);
437 void PlacesItemModelTest::testDefaultViewProperties_data()
439 QTest::addColumn
<QUrl
>("url");
440 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
441 QTest::addColumn
<bool>("expectedPreviewShow");
442 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
445 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
448 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
451 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
454 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
458 void PlacesItemModelTest::testDefaultViewProperties()
461 QFETCH(DolphinView::Mode
, expectedViewMode
);
462 QFETCH(bool, expectedPreviewShow
);
463 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
465 // In order to test the default view properties, turn off the global view properties and re-init the test to reload the model.
466 GeneralSettings
* settings
= GeneralSettings::self();
467 settings
->setGlobalViewProps(false);
472 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
473 QCOMPARE(properties
.viewMode(), expectedViewMode
);
474 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
475 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
477 settings
->setGlobalViewProps(true);
481 void PlacesItemModelTest::testClear()
483 QCOMPARE(m_model
->count(), m_expectedModelCount
);
485 QCOMPARE(m_model
->count(), 0);
486 QCOMPARE(m_model
->hiddenCount(), 0);
488 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
491 void PlacesItemModelTest::testHideItem()
493 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
494 const int index
= indexOf(mediaUrl
);
496 PlacesItem
*item
= m_model
->placesItem(index
);
498 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
499 QList
<QVariant
> spyItemsRemovedArgs
;
500 KItemRangeList removedRange
;
502 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
503 QList
<QVariant
> spyItemsInsertedArgs
;
504 KItemRangeList insertedRange
;
508 item
->setHidden(true);
510 // check if items removed was fired
511 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
- 1);
512 QCOMPARE(spyItemsRemoved
.count(), 1);
513 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
514 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
515 QCOMPARE(removedRange
.size(), 1);
516 QCOMPARE(removedRange
.first().index
, index
);
517 QCOMPARE(removedRange
.first().count
, 1);
519 // allow model to show hidden items
520 m_model
->setHiddenItemsShown(true);
522 // check if the items inserted was fired
523 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
524 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
525 QCOMPARE(insertedRange
.size(), 1);
526 QCOMPARE(insertedRange
.first().index
, index
);
527 QCOMPARE(insertedRange
.first().count
, 1);
529 // mark item as visible
530 item
= m_model
->placesItem(index
);
531 item
->setHidden(false);
533 // mark model to hide invisible items
534 m_model
->setHiddenItemsShown(true);
536 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
539 void PlacesItemModelTest::testSystemItems()
541 int tempDirIndex
= 2;
542 if (m_hasDesktopFolder
) {
545 if (m_hasDocumentsFolder
) {
548 if (m_hasDownloadsFolder
) {
552 QCOMPARE(m_model
->count(), m_expectedModelCount
);
553 for (int r
= 0; r
< m_model
->count(); r
++) {
554 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
557 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
559 // create a new entry (non system item)
560 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
562 // check if the new entry was created
563 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
565 // make sure the new place get removed
566 schedulePlaceRemoval(tempDirIndex
);
568 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
569 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
570 QCOMPARE(range
.first().index
, tempDirIndex
);
571 QCOMPARE(range
.first().count
, 1);
572 QVERIFY(!m_model
->placesItem(tempDirIndex
)->isSystemItem());
573 QCOMPARE(m_model
->count(), m_expectedModelCount
+ 1);
576 // check if the removal signal is correct
577 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
578 m_model
->deleteItem(tempDirIndex
);
579 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
580 args
= itemsRemovedSpy
.takeFirst();
581 range
= args
.at(0).value
<KItemRangeList
>();
582 QCOMPARE(range
.first().index
, tempDirIndex
);
583 QCOMPARE(range
.first().count
, 1);
584 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
586 //cancel removal (it was removed above)
587 cancelPlaceRemoval(tempDirIndex
);
590 void PlacesItemModelTest::testEditBookmark()
592 int tempDirIndex
= 2;
593 if (m_hasDesktopFolder
) {
596 if (m_hasDocumentsFolder
) {
599 if (m_hasDownloadsFolder
) {
603 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
605 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
607 // make sure that the new item will be removed later
608 schedulePlaceRemoval(tempDirIndex
);
610 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
613 m_model
->item(tempDirIndex
)->setText(QStringLiteral("Renamed place"));
616 // check if the correct signal was fired
617 QTRY_COMPARE(itemsChangedSply
.count(), 1);
618 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
619 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
620 QCOMPARE(range
.first().index
, tempDirIndex
);
621 QCOMPARE(range
.first().count
, 1);
622 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
623 QCOMPARE(roles
.size(), 1);
624 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
625 QCOMPARE(m_model
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
627 // check if the item was updated in the other model
628 QTRY_COMPARE(other
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
631 void PlacesItemModelTest::testEditAfterCreation()
633 int tempDirIndex
= 2;
634 if (m_hasDesktopFolder
) {
637 if (m_hasDocumentsFolder
) {
640 if (m_hasDownloadsFolder
) {
644 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
645 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
647 // create a new place
648 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
649 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
651 PlacesItemModel
*model
= new PlacesItemModel();
652 QTRY_COMPARE(model
->count(), m_model
->count());
654 // make sure that the new item will be removed later
655 schedulePlaceRemoval(tempDirIndex
);
658 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
659 item
->setText(QStringLiteral("Renamed place"));
662 // check if the second model got the changes
663 QTRY_COMPARE(model
->count(), m_model
->count());
664 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
665 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
666 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
667 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
668 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
671 void PlacesItemModelTest::testEditMetadata()
673 int tempDirIndex
= 2;
674 if (m_hasDesktopFolder
) {
677 if (m_hasDocumentsFolder
) {
680 if (m_hasDownloadsFolder
) {
684 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
685 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
687 // create a new place
688 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
689 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
691 // check if the new entry was created
692 PlacesItemModel
*model
= new PlacesItemModel();
693 QTRY_COMPARE(model
->count(), m_model
->count());
695 // make sure that the new item will be removed later
696 schedulePlaceRemoval(tempDirIndex
);
698 // modify place metadata
699 auto bookmark
= m_model
->placesItem(tempDirIndex
)->bookmark();
700 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
703 // check if the place was modified in both models
704 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
705 KAboutData::applicationData().componentName());
706 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
707 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
708 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
709 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
710 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
713 void PlacesItemModelTest::testRefresh()
715 int tempDirIndex
= 2;
716 if (m_hasDesktopFolder
) {
719 if (m_hasDocumentsFolder
) {
722 if (m_hasDownloadsFolder
) {
726 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
727 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
729 // create a new place
730 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
731 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
733 PlacesItemModel
*model
= new PlacesItemModel();
734 QTRY_COMPARE(model
->count(), m_model
->count());
736 // make sure that the new item will be removed later
737 schedulePlaceRemoval(tempDirIndex
);
739 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
740 PlacesItem
*sameItem
= model
->placesItem(tempDirIndex
);
741 QCOMPARE(item
->text(), sameItem
->text());
744 item
->setText(QStringLiteral("Renamed place"));
746 // item from another model is not affected at the moment
747 QVERIFY(item
->text() != sameItem
->text());
752 // item must be equal
753 QTRY_COMPARE(item
->text(), sameItem
->text());
756 void PlacesItemModelTest::testIcons_data()
758 QTest::addColumn
<QUrl
>("url");
759 QTest::addColumn
<QString
>("expectedIconName");
762 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
765 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
768 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
771 void PlacesItemModelTest::testIcons()
774 QFETCH(QString
, expectedIconName
);
776 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
777 QCOMPARE(item
->icon(), expectedIconName
);
779 for (int r
= 0; r
< m_model
->count(); r
++) {
780 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
784 void PlacesItemModelTest::testDragAndDrop()
786 int lastIndex
= 1; // last index of places group
787 if (m_hasDesktopFolder
) {
790 if (m_hasDocumentsFolder
) {
793 if (m_hasDownloadsFolder
) {
797 QList
<QVariant
> args
;
798 KItemRangeList range
;
799 QStringList urls
= initialUrls();
801 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
802 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
804 CHECK_PLACES_URLS(initialUrls());
805 // Move the home directory to the end of the places group
806 QMimeData
*dropData
= createMimeData(QList
<int>() << 0);
807 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
808 urls
.move(0, lastIndex
);
811 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
812 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
814 // remove item from actual position
815 args
= itemsRemovedSpy
.takeFirst();
816 range
= args
.at(0).value
<KItemRangeList
>();
817 QCOMPARE(range
.size(), 1);
818 QCOMPARE(range
.at(0).count
, 1);
819 QCOMPARE(range
.at(0).index
, 0);
821 // insert intem in his group
822 args
= itemsInsertedSpy
.takeFirst();
823 range
= args
.at(0).value
<KItemRangeList
>();
824 QCOMPARE(range
.size(), 1);
825 QCOMPARE(range
.at(0).count
, 1);
826 QCOMPARE(range
.at(0).index
, lastIndex
);
828 CHECK_PLACES_URLS(urls
);
830 itemsInsertedSpy
.clear();
831 itemsRemovedSpy
.clear();
833 // Move home directory item back to its original position
834 dropData
= createMimeData(QList
<int>() << lastIndex
);
835 m_model
->dropMimeDataBefore(0, dropData
);
836 urls
.move(lastIndex
, 0);
839 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
840 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
842 // remove item from actual position
843 args
= itemsRemovedSpy
.takeFirst();
844 range
= args
.at(0).value
<KItemRangeList
>();
845 QCOMPARE(range
.size(), 1);
846 QCOMPARE(range
.at(0).count
, 1);
847 QCOMPARE(range
.at(0).index
, lastIndex
);
849 // insert intem in the requested position
850 args
= itemsInsertedSpy
.takeFirst();
851 range
= args
.at(0).value
<KItemRangeList
>();
852 QCOMPARE(range
.size(), 1);
853 QCOMPARE(range
.at(0).count
, 1);
854 QCOMPARE(range
.at(0).index
, 0);
856 CHECK_PLACES_URLS(urls
);
859 void PlacesItemModelTest::testHideDevices()
861 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
862 QStringList urls
= initialUrls();
864 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
865 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
866 QTRY_COMPARE(itemsRemoved
.count(), 3);
868 // remove removable-devices
869 urls
.removeOne(QStringLiteral("/media/floppy0"));
870 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
871 urls
.removeOne(QStringLiteral("/media/cdrom"));
873 // check if the correct urls was removed
874 CHECK_PLACES_URLS(urls
);
877 m_model
= new PlacesItemModel();
878 QTRY_COMPARE(m_model
->count(), urls
.count());
879 CHECK_PLACES_URLS(urls
);
882 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
883 urls
= initialUrls();
884 QTRY_COMPARE(m_model
->count(), urls
.count());
885 CHECK_PLACES_URLS(urls
);
888 void PlacesItemModelTest::testDuplicatedEntries()
890 QStringList urls
= initialUrls();
891 // create a duplicated entry on bookmark
892 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
893 KBookmarkGroup root
= bookmarkManager
->root();
894 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
896 const QString id
= QUuid::createUuid().toString();
897 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
898 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
899 bookmarkManager
->emitChanged(bookmarkManager
->root());
901 PlacesItemModel
*newModel
= new PlacesItemModel();
902 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
903 QTRY_COMPARE(urls
, placesUrls(newModel
));
907 void PlacesItemModelTest::renameAfterCreation()
909 int tempDirIndex
= 2;
910 if (m_hasDesktopFolder
) {
913 if (m_hasDocumentsFolder
) {
916 if (m_hasDownloadsFolder
) {
920 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
921 QStringList urls
= initialUrls();
922 PlacesItemModel
*model
= new PlacesItemModel();
924 CHECK_PLACES_URLS(urls
);
925 QTRY_COMPARE(model
->count(), m_model
->count());
927 // create a new place
928 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
929 urls
.insert(tempDirIndex
, tempUrl
.toLocalFile());
931 // make sure that the new item will be removed later
932 schedulePlaceRemoval(tempDirIndex
);
934 CHECK_PLACES_URLS(urls
);
935 QCOMPARE(model
->count(), m_model
->count());
939 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
941 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
942 item
->setText(QStringLiteral("New Temporary Dir"));
943 item
->setUrl(item
->url());
944 item
->setIcon(item
->icon());
947 QTRY_COMPARE(changedSpy
.count(), 1);
949 // check if the place was modified in both models
950 QTRY_COMPARE(m_model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
951 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
954 QTEST_MAIN(PlacesItemModelTest
)
956 #include "placesitemmodeltest.moc"