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 "panels/places/placesitemmodel.h"
33 #include "panels/places/placesitem.h"
34 #include "views/viewproperties.h"
36 Q_DECLARE_METATYPE(KItemRangeList
)
37 Q_DECLARE_METATYPE(KItemRange
)
40 //c:\ as root for windows
41 #define KDE_ROOT_PATH "C:\\"
43 #define KDE_ROOT_PATH "/"
46 static QString
bookmarksFile()
48 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + "/user-places.xbel";
51 class PlacesItemModelTest
: public QObject
60 void cleanupTestCase();
64 void testDeletePlace();
65 void testPlaceItem_data();
67 void testTearDownDevice();
68 void testDefaultViewProperties_data();
69 void testDefaultViewProperties();
72 void testSystemItems();
73 void testEditBookmark();
74 void testEditAfterCreation();
75 void testEditMetadata();
77 void testIcons_data();
79 void testDragAndDrop();
80 void testHideDevices();
81 void testDuplicatedEntries();
82 void renameAfterCreation();
85 PlacesItemModel
* m_model
;
86 QSet
<int> m_tobeRemoved
;
87 QMap
<QString
, QDBusInterface
*> m_interfacesMap
;
88 int m_expectedModelCount
= 15;
89 bool m_hasDesktopFolder
= false;
90 bool m_hasDownloadsFolder
= false;
92 void setBalooEnabled(bool enabled
);
93 int indexOf(const QUrl
&url
);
94 QDBusInterface
*fakeManager();
95 QDBusInterface
*fakeDevice(const QString
&udi
);
96 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
97 QStringList
initialUrls() const;
98 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
99 void removePlaceAfter(int index
);
100 void cancelPlaceRemoval(int index
);
101 void removeTestUserData();
102 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
105 #define CHECK_PLACES_URLS(urls) \
107 QStringList places = placesUrls(); \
108 if (places != urls) { \
109 qWarning() << "Expected:" << urls; \
110 qWarning() << "Got:" << places; \
111 QCOMPARE(places, urls); \
115 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
117 KConfig
config(QStringLiteral("baloofilerc"));
118 KConfigGroup basicSettings
= config
.group("Basic Settings");
119 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
123 int PlacesItemModelTest::indexOf(const QUrl
&url
)
125 for (int r
= 0; r
< m_model
->count(); r
++) {
126 if (m_model
->placesItem(r
)->url() == url
) {
133 QDBusInterface
*PlacesItemModelTest::fakeManager()
135 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
138 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
140 if (m_interfacesMap
.contains(udi
)) {
141 return m_interfacesMap
[udi
];
144 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
145 m_interfacesMap
[udi
] = iface
;
150 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
157 for (int row
= 0; row
< model
->count(); ++row
) {
158 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
163 QStringList
PlacesItemModelTest::initialUrls() const
165 static QStringList urls
;
166 if (urls
.isEmpty()) {
167 urls
<< QDir::homePath();
169 if (m_hasDesktopFolder
) {
170 urls
<< QDir::homePath() + QStringLiteral("/Desktop");
173 if (m_hasDownloadsFolder
) {
174 urls
<< QDir::homePath() + QStringLiteral("/Downloads");
177 urls
<< QStringLiteral(KDE_ROOT_PATH
) << QStringLiteral("trash:/")
178 << QStringLiteral("remote:/")
179 << QStringLiteral("/media/nfs")
180 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
181 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
182 << QStringLiteral("/foreign")
183 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
188 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
190 m_model
->createPlacesItem(text
, url
, icon
);
193 void PlacesItemModelTest::removePlaceAfter(int index
)
195 m_tobeRemoved
.insert(index
);
198 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
200 m_tobeRemoved
.remove(index
);
203 void PlacesItemModelTest::removeTestUserData()
205 // user hardcoded path to avoid removal of any user personal data
206 QDir
dir(QStringLiteral("/home/renato/.qttest/share/placesitemmodeltest"));
208 QVERIFY(dir
.removeRecursively());
212 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
215 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
218 for (int index
: indexes
) {
219 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
220 if (itemUrl
.isValid()) {
226 QMimeData
* mimeData
= new QMimeData();
227 mimeData
->setUrls(urls
);
228 // copied from PlacesItemModel::internalMimeType()
229 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
230 QString::number((qptrdiff
)m_model
);
231 mimeData
->setData(internalMimeType
, itemData
);
235 void PlacesItemModelTest::init()
237 m_model
= new PlacesItemModel();
238 // WORKAROUND: need to wait for bookmark to load, check: PlacesItemModel::updateBookmarks
240 QCOMPARE(m_model
->count(), m_expectedModelCount
);
243 void PlacesItemModelTest::cleanup()
245 const auto tobeRemoved
= m_tobeRemoved
;
246 for (const int i
: tobeRemoved
) {
247 int before
= m_model
->count();
248 m_model
->deleteItem(i
);
249 QTRY_COMPARE(m_model
->count(), before
- 1);
251 m_tobeRemoved
.clear();
254 removeTestUserData();
257 void PlacesItemModelTest::initTestCase()
259 QStandardPaths::setTestModeEnabled(true);
260 // remove test user data
261 removeTestUserData();
263 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
264 QVERIFY(!fakeHw
.isEmpty());
265 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
267 setBalooEnabled(true);
268 const QString bookmarsFileName
= bookmarksFile();
269 if (QFileInfo::exists(bookmarsFileName
)) {
270 // Ensure we'll have a clean bookmark file to start
271 QVERIFY(QFile::remove(bookmarsFileName
));
274 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation
)).exists()) {
275 m_hasDesktopFolder
= true;
276 m_expectedModelCount
++;
279 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation
)).exists()) {
280 m_hasDownloadsFolder
= true;
281 m_expectedModelCount
++;
284 qRegisterMetaType
<KItemRangeList
>();
285 qRegisterMetaType
<KItemRange
>();
288 void PlacesItemModelTest::cleanupTestCase()
290 qDeleteAll(m_interfacesMap
);
291 QFile::remove(bookmarksFile());
293 // Remove any previous properties file
294 removeTestUserData();
297 void PlacesItemModelTest::testModelSort()
299 CHECK_PLACES_URLS(initialUrls());
302 void PlacesItemModelTest::testGroups()
304 const auto groups
= m_model
->groups();
305 int expectedGroupSize
= 3;
306 if (m_hasDesktopFolder
) {
309 if (m_hasDownloadsFolder
) {
313 QCOMPARE(groups
.size(), 6);
315 QCOMPARE(groups
.at(0).first
, 0);
316 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
318 QCOMPARE(groups
.at(1).first
, expectedGroupSize
);
319 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
321 QCOMPARE(groups
.at(2).first
, expectedGroupSize
+ 2);
322 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recently Saved"));
324 QCOMPARE(groups
.at(3).first
, expectedGroupSize
+ 4);
325 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
327 QCOMPARE(groups
.at(4).first
, expectedGroupSize
+ 8);
328 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
330 QCOMPARE(groups
.at(5).first
, expectedGroupSize
+ 9);
331 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
334 void PlacesItemModelTest::testPlaceItem_data()
336 QTest::addColumn
<QUrl
>("url");
337 QTest::addColumn
<bool>("expectedIsHidden");
338 QTest::addColumn
<bool>("expectedIsSystemItem");
339 QTest::addColumn
<QString
>("expectedGroup");
340 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
343 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
346 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
349 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recently Saved") << false;
352 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
355 void PlacesItemModelTest::testPlaceItem()
358 QFETCH(bool, expectedIsHidden
);
359 QFETCH(bool, expectedIsSystemItem
);
360 QFETCH(QString
, expectedGroup
);
361 QFETCH(bool, expectedStorageSetupNeeded
);
363 const int index
= indexOf(url
);
364 PlacesItem
*item
= m_model
->placesItem(index
);
365 QCOMPARE(item
->url(), url
);
366 QCOMPARE(item
->isHidden(), expectedIsHidden
);
367 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
368 QCOMPARE(item
->group(), expectedGroup
);
369 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
372 void PlacesItemModelTest::testDeletePlace()
374 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
375 QStringList urls
= initialUrls();
376 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
377 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
379 PlacesItemModel
*model
= new PlacesItemModel();
381 int tempDirIndex
= 3;
382 if (m_hasDesktopFolder
) {
385 if (m_hasDownloadsFolder
) {
389 // create a new place
390 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
391 urls
.insert(tempDirIndex
, tempUrl
.toLocalFile());
393 // check if the new entry was created
394 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
395 CHECK_PLACES_URLS(urls
);
396 QTRY_COMPARE(model
->count(), m_model
->count());
399 m_model
->deleteItem(tempDirIndex
);
401 // make sure that the new item is removed
402 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
403 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
404 CHECK_PLACES_URLS(initialUrls());
405 QTRY_COMPARE(model
->count(), m_model
->count());
408 void PlacesItemModelTest::testTearDownDevice()
410 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
411 int index
= indexOf(mediaUrl
);
412 QVERIFY(index
!= -1);
414 auto ejectAction
= m_model
->ejectAction(index
);
415 QVERIFY(!ejectAction
);
417 auto teardownAction
= m_model
->teardownAction(index
);
418 QVERIFY(teardownAction
);
420 QCOMPARE(m_model
->count(), m_expectedModelCount
);
422 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
423 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
424 QTRY_COMPARE(m_model
->count(), 16);
425 QCOMPARE(spyItemsRemoved
.count(), 1);
426 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
427 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
428 QCOMPARE(removedRange
.size(), 1);
429 QCOMPARE(removedRange
.first().index
, index
);
430 QCOMPARE(removedRange
.first().count
, 1);
432 QCOMPARE(indexOf(mediaUrl
), -1);
434 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
435 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
436 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
437 QCOMPARE(spyItemsInserted
.count(), 1);
438 index
= indexOf(mediaUrl
);
440 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
441 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
442 QCOMPARE(insertedRange
.size(), 1);
443 QCOMPARE(insertedRange
.first().index
, index
);
444 QCOMPARE(insertedRange
.first().count
, 1);
447 void PlacesItemModelTest::testDefaultViewProperties_data()
449 QTest::addColumn
<QUrl
>("url");
450 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
451 QTest::addColumn
<bool>("expectedPreviewShow");
452 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
455 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
458 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
461 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
464 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
467 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
471 void PlacesItemModelTest::testDefaultViewProperties()
474 QFETCH(DolphinView::Mode
, expectedViewMode
);
475 QFETCH(bool, expectedPreviewShow
);
476 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
478 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
479 QCOMPARE(properties
.viewMode(), expectedViewMode
);
480 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
481 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
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(), 16);
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 QCOMPARE(m_model
->count(), m_expectedModelCount
);
545 for (int r
= 0; r
< m_model
->count(); r
++) {
546 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
549 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
551 // create a new entry (non system item)
552 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
554 // check if the new entry was created
555 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
557 // make sure the new place get removed
560 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
561 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
562 QCOMPARE(range
.first().index
, 5);
563 QCOMPARE(range
.first().count
, 1);
564 QVERIFY(!m_model
->placesItem(5)->isSystemItem());
565 QCOMPARE(m_model
->count(), 18);
568 // check if the removal signal is correct
569 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
570 m_model
->deleteItem(5);
571 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
572 args
= itemsRemovedSpy
.takeFirst();
573 range
= args
.at(0).value
<KItemRangeList
>();
574 QCOMPARE(range
.first().index
, 5);
575 QCOMPARE(range
.first().count
, 1);
576 QTRY_COMPARE(m_model
->count(), m_expectedModelCount
);
578 //cancel removal (it was removed above)
579 cancelPlaceRemoval(5);
582 void PlacesItemModelTest::testEditBookmark()
584 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
586 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
588 // make sure that the new item will be removed later
591 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
594 m_model
->item(3)->setText(QStringLiteral("Renamed place"));
597 // check if the correct signal was fired
598 QTRY_COMPARE(itemsChangedSply
.count(), 1);
599 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
600 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
601 QCOMPARE(range
.first().index
, 3);
602 QCOMPARE(range
.first().count
, 1);
603 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
604 QCOMPARE(roles
.size(), 1);
605 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
606 QCOMPARE(m_model
->item(3)->text(), QStringLiteral("Renamed place"));
608 // check if the item was updated in the other model
609 QTRY_COMPARE(other
->item(3)->text(), QStringLiteral("Renamed place"));
612 void PlacesItemModelTest::testEditAfterCreation()
614 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
615 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
617 // create a new place
618 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
619 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
621 PlacesItemModel
*model
= new PlacesItemModel();
622 QTRY_COMPARE(model
->count(), m_model
->count());
624 // make sure that the new item will be removed later
628 PlacesItem
*item
= m_model
->placesItem(3);
629 item
->setText(QStringLiteral("Renamed place"));
632 // check if the second model got the changes
633 QTRY_COMPARE(model
->count(), m_model
->count());
634 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
635 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
636 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
637 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
638 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
641 void PlacesItemModelTest::testEditMetadata()
643 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
644 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
646 // create a new place
647 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
648 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
650 // check if the new entry was created
651 PlacesItemModel
*model
= new PlacesItemModel();
652 QTRY_COMPARE(model
->count(), m_model
->count());
654 // make sure that the new item will be removed later
657 // modify place metadata
658 PlacesItem
*item
= m_model
->placesItem(3);
659 item
->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
662 // check if the place was modified in both models
663 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
664 KAboutData::applicationData().componentName());
665 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
666 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
667 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
668 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
669 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
672 void PlacesItemModelTest::testRefresh()
674 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
675 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
677 // create a new place
678 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
679 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
681 PlacesItemModel
*model
= new PlacesItemModel();
682 QTRY_COMPARE(model
->count(), m_model
->count());
684 // make sure that the new item will be removed later
687 PlacesItem
*item
= m_model
->placesItem(5);
688 PlacesItem
*sameItem
= model
->placesItem(5);
689 QCOMPARE(item
->text(), sameItem
->text());
692 item
->setText(QStringLiteral("Renamed place"));
694 // item from another model is not affected at the moment
695 QVERIFY(item
->text() != sameItem
->text());
700 // item must be equal
701 QTRY_COMPARE(item
->text(), sameItem
->text());
704 void PlacesItemModelTest::testIcons_data()
706 QTest::addColumn
<QUrl
>("url");
707 QTest::addColumn
<QString
>("expectedIconName");
710 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
713 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
716 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << QStringLiteral("go-jump-today");
719 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
722 void PlacesItemModelTest::testIcons()
725 QFETCH(QString
, expectedIconName
);
727 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
728 QCOMPARE(item
->icon(), expectedIconName
);
730 for (int r
= 0; r
< m_model
->count(); r
++) {
731 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
735 void PlacesItemModelTest::testDragAndDrop()
737 QList
<QVariant
> args
;
738 KItemRangeList range
;
739 QStringList urls
= initialUrls();
740 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
741 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
743 CHECK_PLACES_URLS(initialUrls());
744 // Move the home directory to the end of the places group
745 QMimeData
*dropData
= createMimeData(QList
<int>() << 0);
746 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
750 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
751 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
753 // remove item from actual position
754 args
= itemsRemovedSpy
.takeFirst();
755 range
= args
.at(0).value
<KItemRangeList
>();
756 QCOMPARE(range
.size(), 1);
757 QCOMPARE(range
.at(0).count
, 1);
758 QCOMPARE(range
.at(0).index
, 0);
760 // insert intem in his group
761 args
= itemsInsertedSpy
.takeFirst();
762 range
= args
.at(0).value
<KItemRangeList
>();
763 QCOMPARE(range
.size(), 1);
764 QCOMPARE(range
.at(0).count
, 1);
765 QCOMPARE(range
.at(0).index
, 4);
767 CHECK_PLACES_URLS(urls
);
769 itemsInsertedSpy
.clear();
770 itemsRemovedSpy
.clear();
772 // Move home directory item back to its original position
773 dropData
= createMimeData(QList
<int>() << 4);
774 m_model
->dropMimeDataBefore(0, dropData
);
778 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
779 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
781 // remove item from actual position
782 args
= itemsRemovedSpy
.takeFirst();
783 range
= args
.at(0).value
<KItemRangeList
>();
784 QCOMPARE(range
.size(), 1);
785 QCOMPARE(range
.at(0).count
, 1);
786 QCOMPARE(range
.at(0).index
, 4);
788 // insert intem in the requested position
789 args
= itemsInsertedSpy
.takeFirst();
790 range
= args
.at(0).value
<KItemRangeList
>();
791 QCOMPARE(range
.size(), 1);
792 QCOMPARE(range
.at(0).count
, 1);
793 QCOMPARE(range
.at(0).index
, 0);
795 CHECK_PLACES_URLS(urls
);
798 void PlacesItemModelTest::testHideDevices()
800 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
801 QStringList urls
= initialUrls();
803 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
804 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
805 QTRY_COMPARE(itemsRemoved
.count(), 3);
807 // remove removable-devices
808 urls
.removeOne(QStringLiteral("/media/floppy0"));
809 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
810 urls
.removeOne(QStringLiteral("/media/cdrom"));
812 // check if the correct urls was removed
813 CHECK_PLACES_URLS(urls
);
816 m_model
= new PlacesItemModel();
817 QTRY_COMPARE(m_model
->count(), urls
.count());
818 CHECK_PLACES_URLS(urls
);
821 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
822 urls
= initialUrls();
823 QTRY_COMPARE(m_model
->count(), urls
.count());
824 CHECK_PLACES_URLS(urls
);
827 void PlacesItemModelTest::testDuplicatedEntries()
829 QStringList urls
= initialUrls();
830 // create a duplicated entry on bookmark
831 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
832 KBookmarkGroup root
= bookmarkManager
->root();
833 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
835 const QString id
= QUuid::createUuid().toString();
836 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
837 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
838 bookmarkManager
->emitChanged(bookmarkManager
->root());
840 PlacesItemModel
*newModel
= new PlacesItemModel();
841 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
842 QTRY_COMPARE(urls
, placesUrls(newModel
));
846 void PlacesItemModelTest::renameAfterCreation()
848 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
849 QStringList urls
= initialUrls();
850 PlacesItemModel
*model
= new PlacesItemModel();
852 CHECK_PLACES_URLS(urls
);
853 QTRY_COMPARE(model
->count(), m_model
->count());
855 // create a new place
856 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
857 urls
.insert(5, tempUrl
.toLocalFile());
859 // make sure that the new item will be removed later
862 CHECK_PLACES_URLS(urls
);
863 QCOMPARE(model
->count(), m_model
->count());
867 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
869 PlacesItem
*item
= m_model
->placesItem(3);
870 item
->setText(QStringLiteral("New Temporary Dir"));
871 item
->setUrl(item
->url());
872 item
->setIcon(item
->icon());
875 QTRY_COMPARE(changedSpy
.count(), 1);
877 // check if the place was modified in both models
878 QTRY_COMPARE(m_model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
879 QTRY_COMPARE(model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
882 QTEST_MAIN(PlacesItemModelTest
)
884 #include "placesitemmodeltest.moc"