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>
32 #include "dolphin_generalsettings.h"
33 #include "panels/places/placesitemmodel.h"
34 #include "panels/places/placesitem.h"
35 #include "views/viewproperties.h"
37 Q_DECLARE_METATYPE(KItemRangeList
)
38 Q_DECLARE_METATYPE(KItemRange
)
41 //c:\ as root for windows
42 #define KDE_ROOT_PATH "C:\\"
44 #define KDE_ROOT_PATH "/"
47 static QString
bookmarksFile()
49 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + "/user-places.xbel";
52 class PlacesItemModelTest
: public QObject
61 void cleanupTestCase();
65 void testDeletePlace();
66 void testPlaceItem_data();
68 void testTearDownDevice();
69 void testDefaultViewProperties_data();
70 void testDefaultViewProperties();
73 void testSystemItems();
74 void testEditBookmark();
75 void testEditAfterCreation();
76 void testEditMetadata();
78 void testIcons_data();
80 void testDragAndDrop();
81 void testHideDevices();
82 void testDuplicatedEntries();
83 void renameAfterCreation();
86 PlacesItemModel
* m_model
;
87 QSet
<int> m_tobeRemoved
;
88 QMap
<QString
, QDBusInterface
*> m_interfacesMap
;
89 int m_expectedModelCount
= 15;
90 bool m_hasDesktopFolder
= false;
91 bool m_hasDownloadsFolder
= false;
93 void setBalooEnabled(bool enabled
);
94 int indexOf(const QUrl
&url
);
95 QDBusInterface
*fakeManager();
96 QDBusInterface
*fakeDevice(const QString
&udi
);
97 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
98 QStringList
initialUrls() const;
99 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
100 void schedulePlaceRemoval(int index
);
101 void cancelPlaceRemoval(int index
);
102 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
103 QTemporaryDir m_tempHomeDir
;
106 #define CHECK_PLACES_URLS(urls) \
108 QStringList places = placesUrls(); \
109 if (places != urls) { \
110 qWarning() << "Expected:" << urls; \
111 qWarning() << "Got:" << places; \
112 QCOMPARE(places, urls); \
116 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
118 KConfig
config(QStringLiteral("baloofilerc"));
119 KConfigGroup basicSettings
= config
.group("Basic Settings");
120 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
124 int PlacesItemModelTest::indexOf(const QUrl
&url
)
126 for (int r
= 0; r
< m_model
->count(); r
++) {
127 if (m_model
->placesItem(r
)->url() == url
) {
134 QDBusInterface
*PlacesItemModelTest::fakeManager()
136 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
139 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
141 if (m_interfacesMap
.contains(udi
)) {
142 return m_interfacesMap
[udi
];
145 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
146 m_interfacesMap
[udi
] = iface
;
151 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
158 for (int row
= 0; row
< model
->count(); ++row
) {
159 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
164 QStringList
PlacesItemModelTest::initialUrls() const
166 static QStringList urls
;
167 if (urls
.isEmpty()) {
168 urls
<< QDir::homePath();
170 if (m_hasDesktopFolder
) {
171 urls
<< QDir::homePath() + QStringLiteral("/Desktop");
174 if (m_hasDownloadsFolder
) {
175 urls
<< QDir::homePath() + QStringLiteral("/Downloads");
178 urls
<< QStringLiteral(KDE_ROOT_PATH
) << QStringLiteral("trash:/")
179 << QStringLiteral("remote:/")
180 << QStringLiteral("/media/nfs")
181 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
182 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
183 << QStringLiteral("/foreign")
184 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
189 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
191 m_model
->createPlacesItem(text
, url
, icon
);
194 void PlacesItemModelTest::schedulePlaceRemoval(int index
)
196 m_tobeRemoved
.insert(index
);
199 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
201 m_tobeRemoved
.remove(index
);
204 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
207 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
210 for (int index
: indexes
) {
211 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
212 if (itemUrl
.isValid()) {
218 QMimeData
* mimeData
= new QMimeData();
219 mimeData
->setUrls(urls
);
220 // copied from PlacesItemModel::internalMimeType()
221 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
222 QString::number((qptrdiff
)m_model
);
223 mimeData
->setData(internalMimeType
, itemData
);
227 void PlacesItemModelTest::init()
229 m_model
= new PlacesItemModel();
230 // WORKAROUND: need to wait for bookmark to load
232 QCOMPARE(m_model
->count(), m_expectedModelCount
);
235 void PlacesItemModelTest::cleanup()
237 const auto tobeRemoved
= m_tobeRemoved
;
238 for (const int i
: tobeRemoved
) {
239 int before
= m_model
->count();
240 m_model
->deleteItem(i
);
241 QTRY_COMPARE(m_model
->count(), before
- 1);
243 m_tobeRemoved
.clear();
248 void PlacesItemModelTest::initTestCase()
250 QVERIFY(m_tempHomeDir
.isValid());
251 QVERIFY(qputenv("HOME", m_tempHomeDir
.path().toUtf8()));
252 QVERIFY(qputenv("KDE_FORK_SLAVES", "yes"));
254 QStandardPaths::setTestModeEnabled(true);
256 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
257 QVERIFY(!fakeHw
.isEmpty());
258 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
260 setBalooEnabled(true);
261 const QString bookmarsFileName
= bookmarksFile();
262 if (QFileInfo::exists(bookmarsFileName
)) {
263 // Ensure we'll have a clean bookmark file to start
264 QVERIFY(QFile::remove(bookmarsFileName
));
267 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation
)).exists()) {
268 m_hasDesktopFolder
= true;
269 m_expectedModelCount
++;
272 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation
)).exists()) {
273 m_hasDownloadsFolder
= true;
274 m_expectedModelCount
++;
277 qRegisterMetaType
<KItemRangeList
>();
278 qRegisterMetaType
<KItemRange
>();
281 void PlacesItemModelTest::cleanupTestCase()
283 qDeleteAll(m_interfacesMap
);
284 QFile::remove(bookmarksFile());
287 void PlacesItemModelTest::testModelSort()
289 CHECK_PLACES_URLS(initialUrls());
292 void PlacesItemModelTest::testGroups()
294 const auto groups
= m_model
->groups();
295 int expectedGroupSize
= 3;
296 if (m_hasDesktopFolder
) {
299 if (m_hasDownloadsFolder
) {
303 QCOMPARE(groups
.size(), 6);
305 QCOMPARE(groups
.at(0).first
, 0);
306 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
308 QCOMPARE(groups
.at(1).first
, expectedGroupSize
);
309 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
311 QCOMPARE(groups
.at(2).first
, expectedGroupSize
+ 2);
312 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recently Saved"));
314 QCOMPARE(groups
.at(3).first
, expectedGroupSize
+ 4);
315 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
317 QCOMPARE(groups
.at(4).first
, expectedGroupSize
+ 8);
318 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
320 QCOMPARE(groups
.at(5).first
, expectedGroupSize
+ 9);
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("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recently Saved") << false;
342 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
345 void PlacesItemModelTest::testPlaceItem()
348 QFETCH(bool, expectedIsHidden
);
349 QFETCH(bool, expectedIsSystemItem
);
350 QFETCH(QString
, expectedGroup
);
351 QFETCH(bool, expectedStorageSetupNeeded
);
353 const int index
= indexOf(url
);
354 PlacesItem
*item
= m_model
->placesItem(index
);
355 QCOMPARE(item
->url(), url
);
356 QCOMPARE(item
->isHidden(), expectedIsHidden
);
357 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
358 QCOMPARE(item
->group(), expectedGroup
);
359 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
362 void PlacesItemModelTest::testDeletePlace()
364 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
365 QStringList urls
= initialUrls();
366 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
367 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
369 PlacesItemModel
*model
= new PlacesItemModel();
371 int tempDirIndex
= 3;
372 if (m_hasDesktopFolder
) {
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("Baloo - Today") << QUrl("timeline:/today") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
457 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
461 void PlacesItemModelTest::testDefaultViewProperties()
464 QFETCH(DolphinView::Mode
, expectedViewMode
);
465 QFETCH(bool, expectedPreviewShow
);
466 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
468 // In order to test the default view properties, turn off the global view properties and re-init the test to reload the model.
469 GeneralSettings
* settings
= GeneralSettings::self();
470 settings
->setGlobalViewProps(false);
475 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
476 QCOMPARE(properties
.viewMode(), expectedViewMode
);
477 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
478 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
480 settings
->setGlobalViewProps(true);
484 void PlacesItemModelTest::testClear()
486 QCOMPARE(m_model
->count(), m_expectedModelCount
);
488 QCOMPARE(m_model
->count(), 0);
489 QCOMPARE(m_model
->hiddenCount(), 0);
491 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
494 void PlacesItemModelTest::testHideItem()
496 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
497 const int index
= indexOf(mediaUrl
);
499 PlacesItem
*item
= m_model
->placesItem(index
);
501 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
502 QList
<QVariant
> spyItemsRemovedArgs
;
503 KItemRangeList removedRange
;
505 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
506 QList
<QVariant
> spyItemsInsertedArgs
;
507 KItemRangeList insertedRange
;
511 item
->setHidden(true);
513 // check if items removed was fired
514 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
- 1);
515 QCOMPARE(spyItemsRemoved
.count(), 1);
516 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
517 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
518 QCOMPARE(removedRange
.size(), 1);
519 QCOMPARE(removedRange
.first().index
, index
);
520 QCOMPARE(removedRange
.first().count
, 1);
522 // allow model to show hidden items
523 m_model
->setHiddenItemsShown(true);
525 // check if the items inserted was fired
526 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
527 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
528 QCOMPARE(insertedRange
.size(), 1);
529 QCOMPARE(insertedRange
.first().index
, index
);
530 QCOMPARE(insertedRange
.first().count
, 1);
532 // mark item as visible
533 item
= m_model
->placesItem(index
);
534 item
->setHidden(false);
536 // mark model to hide invisible items
537 m_model
->setHiddenItemsShown(true);
539 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
542 void PlacesItemModelTest::testSystemItems()
544 int tempDirIndex
= 3;
545 if (m_hasDesktopFolder
) {
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
= 1;
593 if (m_hasDesktopFolder
) {
596 if (m_hasDownloadsFolder
) {
600 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
602 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
604 // make sure that the new item will be removed later
605 schedulePlaceRemoval(tempDirIndex
+ 2);
607 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
610 m_model
->item(tempDirIndex
)->setText(QStringLiteral("Renamed place"));
613 // check if the correct signal was fired
614 QTRY_COMPARE(itemsChangedSply
.count(), 1);
615 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
616 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
617 QCOMPARE(range
.first().index
, tempDirIndex
);
618 QCOMPARE(range
.first().count
, 1);
619 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
620 QCOMPARE(roles
.size(), 1);
621 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
622 QCOMPARE(m_model
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
624 // check if the item was updated in the other model
625 QTRY_COMPARE(other
->item(tempDirIndex
)->text(), QStringLiteral("Renamed place"));
628 void PlacesItemModelTest::testEditAfterCreation()
630 int tempDirIndex
= 1;
631 if (m_hasDesktopFolder
) {
634 if (m_hasDownloadsFolder
) {
638 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
639 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
641 // create a new place
642 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
643 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
645 PlacesItemModel
*model
= new PlacesItemModel();
646 QTRY_COMPARE(model
->count(), m_model
->count());
648 // make sure that the new item will be removed later
649 schedulePlaceRemoval(tempDirIndex
+ 2);
652 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
653 item
->setText(QStringLiteral("Renamed place"));
656 // check if the second model got the changes
657 QTRY_COMPARE(model
->count(), m_model
->count());
658 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
659 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
660 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
661 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
662 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
665 void PlacesItemModelTest::testEditMetadata()
667 int tempDirIndex
= 1;
668 if (m_hasDesktopFolder
) {
671 if (m_hasDownloadsFolder
) {
675 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
676 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
678 // create a new place
679 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
680 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
682 // check if the new entry was created
683 PlacesItemModel
*model
= new PlacesItemModel();
684 QTRY_COMPARE(model
->count(), m_model
->count());
686 // make sure that the new item will be removed later
687 schedulePlaceRemoval(tempDirIndex
+ 2);
689 // modify place metadata
690 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
691 item
->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
694 // check if the place was modified in both models
695 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
696 KAboutData::applicationData().componentName());
697 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), m_model
->placesItem(tempDirIndex
)->text());
698 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
699 m_model
->placesItem(tempDirIndex
)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
700 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->icon(), m_model
->placesItem(tempDirIndex
)->icon());
701 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->url(), m_model
->placesItem(tempDirIndex
)->url());
704 void PlacesItemModelTest::testRefresh()
706 int tempDirIndex
= 3;
707 if (m_hasDesktopFolder
) {
710 if (m_hasDownloadsFolder
) {
714 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
715 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
717 // create a new place
718 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
719 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
721 PlacesItemModel
*model
= new PlacesItemModel();
722 QTRY_COMPARE(model
->count(), m_model
->count());
724 // make sure that the new item will be removed later
725 schedulePlaceRemoval(tempDirIndex
);
727 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
728 PlacesItem
*sameItem
= model
->placesItem(tempDirIndex
);
729 QCOMPARE(item
->text(), sameItem
->text());
732 item
->setText(QStringLiteral("Renamed place"));
734 // item from another model is not affected at the moment
735 QVERIFY(item
->text() != sameItem
->text());
740 // item must be equal
741 QTRY_COMPARE(item
->text(), sameItem
->text());
744 void PlacesItemModelTest::testIcons_data()
746 QTest::addColumn
<QUrl
>("url");
747 QTest::addColumn
<QString
>("expectedIconName");
750 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
753 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
756 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << QStringLiteral("go-jump-today");
759 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
762 void PlacesItemModelTest::testIcons()
765 QFETCH(QString
, expectedIconName
);
767 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
768 QCOMPARE(item
->icon(), expectedIconName
);
770 for (int r
= 0; r
< m_model
->count(); r
++) {
771 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
775 void PlacesItemModelTest::testDragAndDrop()
777 int lastIndex
= 2; // last index of places group
778 if (m_hasDesktopFolder
) {
781 if (m_hasDownloadsFolder
) {
785 QList
<QVariant
> args
;
786 KItemRangeList range
;
787 QStringList urls
= initialUrls();
788 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
789 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
791 CHECK_PLACES_URLS(initialUrls());
792 // Move the home directory to the end of the places group
793 QMimeData
*dropData
= createMimeData(QList
<int>() << 0);
794 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
795 urls
.move(0, lastIndex
);
798 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
799 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
801 // remove item from actual position
802 args
= itemsRemovedSpy
.takeFirst();
803 range
= args
.at(0).value
<KItemRangeList
>();
804 QCOMPARE(range
.size(), 1);
805 QCOMPARE(range
.at(0).count
, 1);
806 QCOMPARE(range
.at(0).index
, 0);
808 // insert intem in his group
809 args
= itemsInsertedSpy
.takeFirst();
810 range
= args
.at(0).value
<KItemRangeList
>();
811 QCOMPARE(range
.size(), 1);
812 QCOMPARE(range
.at(0).count
, 1);
813 QCOMPARE(range
.at(0).index
, lastIndex
);
815 CHECK_PLACES_URLS(urls
);
817 itemsInsertedSpy
.clear();
818 itemsRemovedSpy
.clear();
820 // Move home directory item back to its original position
821 dropData
= createMimeData(QList
<int>() << lastIndex
);
822 m_model
->dropMimeDataBefore(0, dropData
);
823 urls
.move(lastIndex
, 0);
826 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
827 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
829 // remove item from actual position
830 args
= itemsRemovedSpy
.takeFirst();
831 range
= args
.at(0).value
<KItemRangeList
>();
832 QCOMPARE(range
.size(), 1);
833 QCOMPARE(range
.at(0).count
, 1);
834 QCOMPARE(range
.at(0).index
, lastIndex
);
836 // insert intem in the requested position
837 args
= itemsInsertedSpy
.takeFirst();
838 range
= args
.at(0).value
<KItemRangeList
>();
839 QCOMPARE(range
.size(), 1);
840 QCOMPARE(range
.at(0).count
, 1);
841 QCOMPARE(range
.at(0).index
, 0);
843 CHECK_PLACES_URLS(urls
);
846 void PlacesItemModelTest::testHideDevices()
848 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
849 QStringList urls
= initialUrls();
851 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
852 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
853 QTRY_COMPARE(itemsRemoved
.count(), 3);
855 // remove removable-devices
856 urls
.removeOne(QStringLiteral("/media/floppy0"));
857 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
858 urls
.removeOne(QStringLiteral("/media/cdrom"));
860 // check if the correct urls was removed
861 CHECK_PLACES_URLS(urls
);
864 m_model
= new PlacesItemModel();
865 QTRY_COMPARE(m_model
->count(), urls
.count());
866 CHECK_PLACES_URLS(urls
);
869 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
870 urls
= initialUrls();
871 QTRY_COMPARE(m_model
->count(), urls
.count());
872 CHECK_PLACES_URLS(urls
);
875 void PlacesItemModelTest::testDuplicatedEntries()
877 QStringList urls
= initialUrls();
878 // create a duplicated entry on bookmark
879 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
880 KBookmarkGroup root
= bookmarkManager
->root();
881 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
883 const QString id
= QUuid::createUuid().toString();
884 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
885 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
886 bookmarkManager
->emitChanged(bookmarkManager
->root());
888 PlacesItemModel
*newModel
= new PlacesItemModel();
889 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
890 QTRY_COMPARE(urls
, placesUrls(newModel
));
894 void PlacesItemModelTest::renameAfterCreation()
896 int tempDirIndex
= 1;
897 if (m_hasDesktopFolder
) {
900 if (m_hasDownloadsFolder
) {
904 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
905 QStringList urls
= initialUrls();
906 PlacesItemModel
*model
= new PlacesItemModel();
908 CHECK_PLACES_URLS(urls
);
909 QTRY_COMPARE(model
->count(), m_model
->count());
911 // create a new place
912 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
913 urls
.insert(tempDirIndex
+ 2, tempUrl
.toLocalFile());
915 // make sure that the new item will be removed later
916 schedulePlaceRemoval(tempDirIndex
+ 2);
918 CHECK_PLACES_URLS(urls
);
919 QCOMPARE(model
->count(), m_model
->count());
923 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
925 PlacesItem
*item
= m_model
->placesItem(tempDirIndex
);
926 item
->setText(QStringLiteral("New Temporary Dir"));
927 item
->setUrl(item
->url());
928 item
->setIcon(item
->icon());
931 QTRY_COMPARE(changedSpy
.count(), 1);
933 // check if the place was modified in both models
934 QTRY_COMPARE(m_model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
935 QTRY_COMPARE(model
->placesItem(tempDirIndex
)->text(), QStringLiteral("New Temporary Dir"));
938 QTEST_MAIN(PlacesItemModelTest
)
940 #include "placesitemmodeltest.moc"