1 /***************************************************************************
2 * Copyright (C) 2017 by Renato Araujo Oliveira <renato.araujo@kdab.com> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
22 #include <QStandardPaths>
24 #include <QDBusInterface>
26 #include <KBookmarkManager>
28 #include <KConfigGroup>
30 #include <KFilePlacesModel>
31 #include <KProtocolInfo>
33 #include "dolphin_generalsettings.h"
34 #include "panels/places/placesitemmodel.h"
35 #include "panels/places/placesitem.h"
36 #include "views/viewproperties.h"
38 Q_DECLARE_METATYPE(KItemRangeList
)
39 Q_DECLARE_METATYPE(KItemRange
)
41 static QString
bookmarksFile()
43 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + "/user-places.xbel";
46 class PlacesItemModelTest
: public QObject
55 void cleanupTestCase();
59 void testDeletePlace();
60 void testPlaceItem_data();
62 void testTearDownDevice();
63 void testDefaultViewProperties_data();
64 void testDefaultViewProperties();
67 void testSystemItems();
68 void testEditBookmark();
69 void testEditAfterCreation();
70 void testEditMetadata();
72 void testIcons_data();
74 void testDragAndDrop();
75 void testHideDevices();
76 void testDuplicatedEntries();
77 void renameAfterCreation();
80 PlacesItemModel
* m_model
;
81 QSet
<int> m_tobeRemoved
;
82 QMap
<QString
, QDBusInterface
*> m_interfacesMap
;
83 int m_expectedModelCount
= qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused")) ? 16 : 14;
84 bool m_hasDesktopFolder
= false;
85 bool m_hasDocumentsFolder
= false;
86 bool m_hasDownloadsFolder
= false;
88 void setBalooEnabled(bool enabled
);
89 int indexOf(const QUrl
&url
);
90 QDBusInterface
*fakeManager();
91 QDBusInterface
*fakeDevice(const QString
&udi
);
92 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
93 QStringList
initialUrls() const;
94 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
95 void schedulePlaceRemoval(int index
);
96 void cancelPlaceRemoval(int index
);
97 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
98 QTemporaryDir m_tempHomeDir
;
101 #define CHECK_PLACES_URLS(urls) \
103 QStringList places = placesUrls(); \
104 if (places != urls) { \
105 qWarning() << "Expected:" << urls; \
106 qWarning() << "Got:" << places; \
107 QCOMPARE(places, urls); \
111 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
113 KConfig
config(QStringLiteral("baloofilerc"));
114 KConfigGroup basicSettings
= config
.group("Basic Settings");
115 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
119 int PlacesItemModelTest::indexOf(const QUrl
&url
)
121 for (int r
= 0; r
< m_model
->count(); r
++) {
122 if (m_model
->placesItem(r
)->url() == url
) {
129 QDBusInterface
*PlacesItemModelTest::fakeManager()
131 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
134 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
136 if (m_interfacesMap
.contains(udi
)) {
137 return m_interfacesMap
[udi
];
140 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
141 m_interfacesMap
[udi
] = iface
;
146 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
153 for (int row
= 0; row
< model
->count(); ++row
) {
154 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
159 QStringList
PlacesItemModelTest::initialUrls() const
161 static QStringList urls
;
162 if (urls
.isEmpty()) {
163 urls
<< QDir::homePath();
165 if (m_hasDesktopFolder
) {
166 urls
<< QDir::homePath() + QStringLiteral("/Desktop");
169 if (m_hasDocumentsFolder
) {
170 urls
<< QDir::homePath() + QStringLiteral("/Documents");
173 if (m_hasDownloadsFolder
) {
174 urls
<< QDir::homePath() + QStringLiteral("/Downloads");
177 urls
<< QStringLiteral("trash:/")
178 << QStringLiteral("remote:/")
179 << QStringLiteral("/media/nfs");
181 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
182 urls
<< QStringLiteral("recentlyused:/files");
183 urls
<< QStringLiteral("recentlyused:/locations");
186 urls
<< QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
187 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
188 << QStringLiteral("/foreign")
189 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
194 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
196 m_model
->createPlacesItem(text
, url
, icon
);
199 void PlacesItemModelTest::schedulePlaceRemoval(int index
)
201 m_tobeRemoved
.insert(index
);
204 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
206 m_tobeRemoved
.remove(index
);
209 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
212 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
215 for (int index
: indexes
) {
216 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
217 if (itemUrl
.isValid()) {
223 QMimeData
* mimeData
= new QMimeData();
224 mimeData
->setUrls(urls
);
225 // copied from PlacesItemModel::internalMimeType()
226 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
227 QString::number((qptrdiff
)m_model
);
228 mimeData
->setData(internalMimeType
, itemData
);
232 void PlacesItemModelTest::init()
234 m_model
= new PlacesItemModel();
235 // WORKAROUND: need to wait for bookmark to load
237 QCOMPARE(m_model
->count(), m_expectedModelCount
);
240 void PlacesItemModelTest::cleanup()
242 const auto tobeRemoved
= m_tobeRemoved
;
243 for (const int i
: tobeRemoved
) {
244 int before
= m_model
->count();
245 m_model
->deleteItem(i
);
246 QTRY_COMPARE(m_model
->count(), before
- 1);
248 m_tobeRemoved
.clear();
253 void PlacesItemModelTest::initTestCase()
255 QVERIFY(m_tempHomeDir
.isValid());
256 QVERIFY(qputenv("HOME", m_tempHomeDir
.path().toUtf8()));
257 QVERIFY(qputenv("KDE_FORK_SLAVES", "yes"));
259 QStandardPaths::setTestModeEnabled(true);
261 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
262 QVERIFY(!fakeHw
.isEmpty());
263 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
265 setBalooEnabled(true);
266 const QString bookmarsFileName
= bookmarksFile();
267 if (QFileInfo::exists(bookmarsFileName
)) {
268 // Ensure we'll have a clean bookmark file to start
269 QVERIFY(QFile::remove(bookmarsFileName
));
272 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation
)).exists()) {
273 m_hasDesktopFolder
= true;
274 m_expectedModelCount
++;
277 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation
)).exists()) {
278 m_hasDocumentsFolder
= true;
279 m_expectedModelCount
++;
282 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation
)).exists()) {
283 m_hasDownloadsFolder
= true;
284 m_expectedModelCount
++;
287 qRegisterMetaType
<KItemRangeList
>();
288 qRegisterMetaType
<KItemRange
>();
291 void PlacesItemModelTest::cleanupTestCase()
293 qDeleteAll(m_interfacesMap
);
294 QFile::remove(bookmarksFile());
297 void PlacesItemModelTest::testModelSort()
299 CHECK_PLACES_URLS(initialUrls());
302 void PlacesItemModelTest::testGroups()
304 const auto groups
= m_model
->groups();
305 int expectedRemoteIndex
= 2;
306 if (m_hasDesktopFolder
) {
307 expectedRemoteIndex
++;
309 if (m_hasDocumentsFolder
) {
310 expectedRemoteIndex
++;
312 if (m_hasDownloadsFolder
) {
313 expectedRemoteIndex
++;
316 QCOMPARE(groups
.size(), 6);
318 QCOMPARE(groups
.at(0).first
, 0);
319 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
321 QCOMPARE(groups
.at(1).first
, expectedRemoteIndex
);
322 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
324 QCOMPARE(groups
.at(2).first
, expectedRemoteIndex
+ 2);
325 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recent"));
327 if (qEnvironmentVariableIsSet("KDE_FULL_SESSION") && KProtocolInfo::isKnownProtocol(QStringLiteral("recentlyused"))) {
328 expectedRemoteIndex
+= 2;
331 QCOMPARE(groups
.at(3).first
, expectedRemoteIndex
+ 4);
332 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
334 QCOMPARE(groups
.at(4).first
, expectedRemoteIndex
+ 8);
335 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
337 QCOMPARE(groups
.at(5).first
, expectedRemoteIndex
+ 9);
338 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
341 void PlacesItemModelTest::testPlaceItem_data()
343 QTest::addColumn
<QUrl
>("url");
344 QTest::addColumn
<bool>("expectedIsHidden");
345 QTest::addColumn
<bool>("expectedIsSystemItem");
346 QTest::addColumn
<QString
>("expectedGroup");
347 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
350 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
353 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
356 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recent") << false;
359 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
362 void PlacesItemModelTest::testPlaceItem()
365 QFETCH(bool, expectedIsHidden
);
366 QFETCH(bool, expectedIsSystemItem
);
367 QFETCH(QString
, expectedGroup
);
368 QFETCH(bool, expectedStorageSetupNeeded
);
370 const int index
= indexOf(url
);
371 PlacesItem
*item
= m_model
->placesItem(index
);
372 QCOMPARE(item
->url(), url
);
373 QCOMPARE(item
->isHidden(), expectedIsHidden
);
374 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
375 QCOMPARE(item
->group(), expectedGroup
);
376 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
379 void PlacesItemModelTest::testDeletePlace()
381 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
382 QStringList urls
= initialUrls();
383 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
384 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
386 PlacesItemModel
*model
= new PlacesItemModel();
388 int tempDirIndex
= 2;
389 if (m_hasDesktopFolder
) {
392 if (m_hasDocumentsFolder
) {
395 if (m_hasDownloadsFolder
) {
399 // create a new place
400 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
401 urls
.insert(tempDirIndex
, tempUrl
.toLocalFile());
403 // check if the new entry was created
404 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
405 CHECK_PLACES_URLS(urls
);
406 QTRY_COMPARE(model
->count(), m_model
->count());
409 m_model
->deleteItem(tempDirIndex
);
411 // make sure that the new item is removed
412 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
413 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
414 CHECK_PLACES_URLS(initialUrls());
415 QTRY_COMPARE(model
->count(), m_model
->count());
418 void PlacesItemModelTest::testTearDownDevice()
420 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
421 int index
= indexOf(mediaUrl
);
422 QVERIFY(index
!= -1);
424 auto ejectAction
= m_model
->ejectAction(index
);
425 QVERIFY(!ejectAction
);
427 auto teardownAction
= m_model
->teardownAction(index
);
428 QVERIFY(teardownAction
);
430 QCOMPARE(m_model
->count(), m_expectedModelCount
);
432 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
433 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
434 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
- 1);
435 QCOMPARE(spyItemsRemoved
.count(), 1);
436 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
437 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
438 QCOMPARE(removedRange
.size(), 1);
439 QCOMPARE(removedRange
.first().index
, index
);
440 QCOMPARE(removedRange
.first().count
, 1);
442 QCOMPARE(indexOf(mediaUrl
), -1);
444 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
445 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
446 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
447 QCOMPARE(spyItemsInserted
.count(), 1);
448 index
= indexOf(mediaUrl
);
450 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
451 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
452 QCOMPARE(insertedRange
.size(), 1);
453 QCOMPARE(insertedRange
.first().index
, index
);
454 QCOMPARE(insertedRange
.first().count
, 1);
457 void PlacesItemModelTest::testDefaultViewProperties_data()
459 QTest::addColumn
<QUrl
>("url");
460 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
461 QTest::addColumn
<bool>("expectedPreviewShow");
462 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
465 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
468 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
471 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
474 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
477 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
481 void PlacesItemModelTest::testDefaultViewProperties()
484 QFETCH(DolphinView::Mode
, expectedViewMode
);
485 QFETCH(bool, expectedPreviewShow
);
486 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
488 // In order to test the default view properties, turn off the global view properties and re-init the test to reload the model.
489 GeneralSettings
* settings
= GeneralSettings::self();
490 settings
->setGlobalViewProps(false);
495 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
496 QCOMPARE(properties
.viewMode(), expectedViewMode
);
497 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
498 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
500 settings
->setGlobalViewProps(true);
504 void PlacesItemModelTest::testClear()
506 QCOMPARE(m_model
->count(), m_expectedModelCount
);
508 QCOMPARE(m_model
->count(), 0);
509 QCOMPARE(m_model
->hiddenCount(), 0);
511 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
514 void PlacesItemModelTest::testHideItem()
516 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
517 const int index
= indexOf(mediaUrl
);
519 PlacesItem
*item
= m_model
->placesItem(index
);
521 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
522 QList
<QVariant
> spyItemsRemovedArgs
;
523 KItemRangeList removedRange
;
525 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
526 QList
<QVariant
> spyItemsInsertedArgs
;
527 KItemRangeList insertedRange
;
531 item
->setHidden(true);
533 // check if items removed was fired
534 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
- 1);
535 QCOMPARE(spyItemsRemoved
.count(), 1);
536 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
537 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
538 QCOMPARE(removedRange
.size(), 1);
539 QCOMPARE(removedRange
.first().index
, index
);
540 QCOMPARE(removedRange
.first().count
, 1);
542 // allow model to show hidden items
543 m_model
->setHiddenItemsShown(true);
545 // check if the items inserted was fired
546 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
547 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
548 QCOMPARE(insertedRange
.size(), 1);
549 QCOMPARE(insertedRange
.first().index
, index
);
550 QCOMPARE(insertedRange
.first().count
, 1);
552 // mark item as visible
553 item
= m_model
->placesItem(index
);
554 item
->setHidden(false);
556 // mark model to hide invisible items
557 m_model
->setHiddenItemsShown(true);
559 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
562 void PlacesItemModelTest::testSystemItems()
564 int tempDirIndex
= 2;
565 if (m_hasDesktopFolder
) {
568 if (m_hasDocumentsFolder
) {
571 if (m_hasDownloadsFolder
) {
575 QCOMPARE(m_model
->count(), m_expectedModelCount
);
576 for (int r
= 0; r
< m_model
->count(); r
++) {
577 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
580 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
582 // create a new entry (non system item)
583 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
585 // check if the new entry was created
586 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
588 // make sure the new place get removed
589 schedulePlaceRemoval(tempDirIndex
);
591 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
592 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
593 QCOMPARE(range
.first().index
, tempDirIndex
);
594 QCOMPARE(range
.first().count
, 1);
595 QVERIFY(!m_model
->placesItem(tempDirIndex
)->isSystemItem());
596 QCOMPARE(m_model
->count(), m_expectedModelCount
+ 1);
599 // check if the removal signal is correct
600 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
601 m_model
->deleteItem(tempDirIndex
);
602 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
603 args
= itemsRemovedSpy
.takeFirst();
604 range
= args
.at(0).value
<KItemRangeList
>();
605 QCOMPARE(range
.first().index
, tempDirIndex
);
606 QCOMPARE(range
.first().count
, 1);
607 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
609 //cancel removal (it was removed above)
610 cancelPlaceRemoval(tempDirIndex
);
613 void PlacesItemModelTest::testEditBookmark()
615 int tempDirIndex
= 2;
616 if (m_hasDesktopFolder
) {
619 if (m_hasDocumentsFolder
) {
622 if (m_hasDownloadsFolder
) {
626 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
628 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
630 // make sure that the new item will be removed later
631 schedulePlaceRemoval(tempDirIndex
);
633 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
636 m_model
->item(tempDirIndex
)->setText(QStringLiteral("Renamed place"));
639 // check if the correct signal was fired
640 QTRY_COMPARE(itemsChangedSply
.count(), 1);
641 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
642 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
643 QCOMPARE(range
.first().index
, tempDirIndex
);
644 QCOMPARE(range
.first().count
, 1);
645 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
646 QCOMPARE(roles
.size(), 1);
647 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
648 QCOMPARE(m_model
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
650 // check if the item was updated in the other model
651 QTRY_COMPARE(other
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
654 void PlacesItemModelTest::testEditAfterCreation()
656 int tempDirIndex
= 2;
657 if (m_hasDesktopFolder
) {
660 if (m_hasDocumentsFolder
) {
663 if (m_hasDownloadsFolder
) {
667 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
668 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
670 // create a new place
671 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
672 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
674 PlacesItemModel
*model
= new PlacesItemModel();
675 QTRY_COMPARE(model
->count(), m_model
->count());
677 // make sure that the new item will be removed later
678 schedulePlaceRemoval(tempDirIndex
);
681 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
682 item
->setText(QStringLiteral("Renamed place"));
685 // check if the second model got the changes
686 QTRY_COMPARE(model
->count(), m_model
->count());
687 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
688 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
689 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
690 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
691 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
694 void PlacesItemModelTest::testEditMetadata()
696 int tempDirIndex
= 2;
697 if (m_hasDesktopFolder
) {
700 if (m_hasDocumentsFolder
) {
703 if (m_hasDownloadsFolder
) {
707 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
708 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
710 // create a new place
711 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
712 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
714 // check if the new entry was created
715 PlacesItemModel
*model
= new PlacesItemModel();
716 QTRY_COMPARE(model
->count(), m_model
->count());
718 // make sure that the new item will be removed later
719 schedulePlaceRemoval(tempDirIndex
);
721 // modify place metadata
722 auto bookmark
= m_model
->placesItem(tempDirIndex
)->bookmark();
723 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
726 // check if the place was modified in both models
727 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
728 KAboutData::applicationData().componentName());
729 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
730 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
731 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
732 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
733 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
736 void PlacesItemModelTest::testRefresh()
738 int tempDirIndex
= 2;
739 if (m_hasDesktopFolder
) {
742 if (m_hasDocumentsFolder
) {
745 if (m_hasDownloadsFolder
) {
749 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
750 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
752 // create a new place
753 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
754 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
756 PlacesItemModel
*model
= new PlacesItemModel();
757 QTRY_COMPARE(model
->count(), m_model
->count());
759 // make sure that the new item will be removed later
760 schedulePlaceRemoval(tempDirIndex
);
762 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
763 PlacesItem
*sameItem
= model
->placesItem(tempDirIndex
);
764 QCOMPARE(item
->text(), sameItem
->text());
767 item
->setText(QStringLiteral("Renamed place"));
769 // item from another model is not affected at the moment
770 QVERIFY(item
->text() != sameItem
->text());
775 // item must be equal
776 QTRY_COMPARE(item
->text(), sameItem
->text());
779 void PlacesItemModelTest::testIcons_data()
781 QTest::addColumn
<QUrl
>("url");
782 QTest::addColumn
<QString
>("expectedIconName");
785 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
788 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
791 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << QStringLiteral("go-jump-today");
794 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
797 void PlacesItemModelTest::testIcons()
800 QFETCH(QString
, expectedIconName
);
802 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
803 QCOMPARE(item
->icon(), expectedIconName
);
805 for (int r
= 0; r
< m_model
->count(); r
++) {
806 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
810 void PlacesItemModelTest::testDragAndDrop()
812 int lastIndex
= 1; // last index of places group
813 if (m_hasDesktopFolder
) {
816 if (m_hasDocumentsFolder
) {
819 if (m_hasDownloadsFolder
) {
823 QList
<QVariant
> args
;
824 KItemRangeList range
;
825 QStringList urls
= initialUrls();
827 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
828 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
830 CHECK_PLACES_URLS(initialUrls());
831 // Move the home directory to the end of the places group
832 QMimeData
*dropData
= createMimeData(QList
<int>() << 0);
833 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
834 urls
.move(0, lastIndex
);
837 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
838 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
840 // remove item from actual position
841 args
= itemsRemovedSpy
.takeFirst();
842 range
= args
.at(0).value
<KItemRangeList
>();
843 QCOMPARE(range
.size(), 1);
844 QCOMPARE(range
.at(0).count
, 1);
845 QCOMPARE(range
.at(0).index
, 0);
847 // insert intem in his group
848 args
= itemsInsertedSpy
.takeFirst();
849 range
= args
.at(0).value
<KItemRangeList
>();
850 QCOMPARE(range
.size(), 1);
851 QCOMPARE(range
.at(0).count
, 1);
852 QCOMPARE(range
.at(0).index
, lastIndex
);
854 CHECK_PLACES_URLS(urls
);
856 itemsInsertedSpy
.clear();
857 itemsRemovedSpy
.clear();
859 // Move home directory item back to its original position
860 dropData
= createMimeData(QList
<int>() << lastIndex
);
861 m_model
->dropMimeDataBefore(0, dropData
);
862 urls
.move(lastIndex
, 0);
865 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
866 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
868 // remove item from actual position
869 args
= itemsRemovedSpy
.takeFirst();
870 range
= args
.at(0).value
<KItemRangeList
>();
871 QCOMPARE(range
.size(), 1);
872 QCOMPARE(range
.at(0).count
, 1);
873 QCOMPARE(range
.at(0).index
, lastIndex
);
875 // insert intem in the requested position
876 args
= itemsInsertedSpy
.takeFirst();
877 range
= args
.at(0).value
<KItemRangeList
>();
878 QCOMPARE(range
.size(), 1);
879 QCOMPARE(range
.at(0).count
, 1);
880 QCOMPARE(range
.at(0).index
, 0);
882 CHECK_PLACES_URLS(urls
);
885 void PlacesItemModelTest::testHideDevices()
887 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
888 QStringList urls
= initialUrls();
890 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
891 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
892 QTRY_COMPARE(itemsRemoved
.count(), 3);
894 // remove removable-devices
895 urls
.removeOne(QStringLiteral("/media/floppy0"));
896 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
897 urls
.removeOne(QStringLiteral("/media/cdrom"));
899 // check if the correct urls was removed
900 CHECK_PLACES_URLS(urls
);
903 m_model
= new PlacesItemModel();
904 QTRY_COMPARE(m_model
->count(), urls
.count());
905 CHECK_PLACES_URLS(urls
);
908 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
909 urls
= initialUrls();
910 QTRY_COMPARE(m_model
->count(), urls
.count());
911 CHECK_PLACES_URLS(urls
);
914 void PlacesItemModelTest::testDuplicatedEntries()
916 QStringList urls
= initialUrls();
917 // create a duplicated entry on bookmark
918 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
919 KBookmarkGroup root
= bookmarkManager
->root();
920 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
922 const QString id
= QUuid::createUuid().toString();
923 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
924 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
925 bookmarkManager
->emitChanged(bookmarkManager
->root());
927 PlacesItemModel
*newModel
= new PlacesItemModel();
928 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
929 QTRY_COMPARE(urls
, placesUrls(newModel
));
933 void PlacesItemModelTest::renameAfterCreation()
935 int tempDirIndex
= 2;
936 if (m_hasDesktopFolder
) {
939 if (m_hasDocumentsFolder
) {
942 if (m_hasDownloadsFolder
) {
946 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
947 QStringList urls
= initialUrls();
948 PlacesItemModel
*model
= new PlacesItemModel();
950 CHECK_PLACES_URLS(urls
);
951 QTRY_COMPARE(model
->count(), m_model
->count());
953 // create a new place
954 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
955 urls
.insert(tempDirIndex
, tempUrl
.toLocalFile());
957 // make sure that the new item will be removed later
958 schedulePlaceRemoval(tempDirIndex
);
960 CHECK_PLACES_URLS(urls
);
961 QCOMPARE(model
->count(), m_model
->count());
965 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
967 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
968 item
->setText(QStringLiteral("New Temporary Dir"));
969 item
->setUrl(item
->url());
970 item
->setIcon(item
->icon());
973 QTRY_COMPARE(changedSpy
.count(), 1);
975 // check if the place was modified in both models
976 QTRY_COMPARE(m_model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
977 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
980 QTEST_MAIN(PlacesItemModelTest
)
982 #include "placesitemmodeltest.moc"