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 ***************************************************************************/
25 #include <QStandardPaths>
27 #include <QDBusInterface>
30 #include <KBookmarkManager>
32 #include <KConfigGroup>
34 #include <KFilePlacesModel>
36 #include "panels/places/placesitemmodel.h"
37 #include "panels/places/placesitem.h"
38 #include "views/viewproperties.h"
39 #include "kitemviews/kitemrange.h"
41 Q_DECLARE_METATYPE(KItemRangeList
)
42 Q_DECLARE_METATYPE(KItemRange
)
45 //c:\ as root for windows
46 #define KDE_ROOT_PATH "C:\\"
48 #define KDE_ROOT_PATH "/"
51 static QString
bookmarksFile()
53 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation
) + "/user-places.xbel";
56 class PlacesItemModelTest
: public QObject
65 void cleanupTestCase();
69 void testDeletePlace();
70 void testPlaceItem_data();
72 void testTearDownDevice();
73 void testDefaultViewProperties_data();
74 void testDefaultViewProperties();
77 void testSystemItems();
78 void testEditBookmark();
79 void testEditAfterCreation();
80 void testEditMetadata();
82 void testIcons_data();
84 void testDragAndDrop();
85 void testHideDevices();
86 void testDuplicatedEntries();
87 void renameAfterCreation();
90 PlacesItemModel
* m_model
;
91 QSet
<int> m_tobeRemoved
;
92 QMap
<QString
, QDBusInterface
*> m_interfacesMap
;
94 void setBalooEnabled(bool enabled
);
95 int indexOf(const QUrl
&url
);
96 QDBusInterface
*fakeManager();
97 QDBusInterface
*fakeDevice(const QString
&udi
);
98 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
99 QStringList
initialUrls() const;
100 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
101 void removePlaceAfter(int index
);
102 void cancelPlaceRemoval(int index
);
103 void removeTestUserData();
104 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
107 #define CHECK_PLACES_URLS(urls) \
109 QStringList places = placesUrls(); \
110 if (places != urls) { \
111 qWarning() << "Expected:" << urls; \
112 qWarning() << "Got:" << places; \
113 QCOMPARE(places, urls); \
117 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
119 KConfig
config(QStringLiteral("baloofilerc"));
120 KConfigGroup basicSettings
= config
.group("Basic Settings");
121 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
125 int PlacesItemModelTest::indexOf(const QUrl
&url
)
127 for (int r
= 0; r
< m_model
->count(); r
++) {
128 if (m_model
->placesItem(r
)->url() == url
) {
135 QDBusInterface
*PlacesItemModelTest::fakeManager()
137 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
140 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
142 if (m_interfacesMap
.contains(udi
)) {
143 return m_interfacesMap
[udi
];
146 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
147 m_interfacesMap
[udi
] = iface
;
152 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
159 for (int row
= 0; row
< model
->count(); ++row
) {
160 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
165 QStringList
PlacesItemModelTest::initialUrls() const
167 static QStringList urls
;
168 if (urls
.isEmpty()) {
169 urls
<< QDir::homePath() << QStringLiteral(KDE_ROOT_PATH
) << QStringLiteral("trash:/")
170 << QStringLiteral("remote:/")
171 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday") << QStringLiteral("timeline:/thismonth") << QStringLiteral("timeline:/lastmonth")
172 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
173 << QStringLiteral("/media/nfs") << QStringLiteral("/foreign")
174 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
179 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
181 m_model
->createPlacesItem(text
, url
, icon
);
184 void PlacesItemModelTest::removePlaceAfter(int index
)
186 m_tobeRemoved
.insert(index
);
189 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
191 m_tobeRemoved
.remove(index
);
194 void PlacesItemModelTest::removeTestUserData()
196 // user hardcoded path to avoid removal of any user personal data
197 QDir
dir(QStringLiteral("/home/renato/.qttest/share/placesitemmodeltest"));
199 QVERIFY(dir
.removeRecursively());
203 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
206 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
209 for (int index
: indexes
) {
210 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
211 if (itemUrl
.isValid()) {
217 QMimeData
* mimeData
= new QMimeData();
218 mimeData
->setUrls(urls
);
219 // copied from PlacesItemModel::internalMimeType()
220 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
221 QString::number((qptrdiff
)m_model
);
222 mimeData
->setData(internalMimeType
, itemData
);
226 void PlacesItemModelTest::init()
228 m_model
= new PlacesItemModel();
229 // WORKAROUND: need to wait for bookmark to load, check: PlacesItemModel::updateBookmarks
231 QCOMPARE(m_model
->count(), 17);
234 void PlacesItemModelTest::cleanup()
236 for (int i
: m_tobeRemoved
) {
237 int before
= m_model
->count();
238 m_model
->deleteItem(i
);
239 QTRY_COMPARE(m_model
->count(), before
- 1);
241 m_tobeRemoved
.clear();
244 removeTestUserData();
247 void PlacesItemModelTest::initTestCase()
249 QStandardPaths::setTestModeEnabled(true);
250 // remove test user data
251 removeTestUserData();
253 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
254 QVERIFY(!fakeHw
.isEmpty());
255 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
257 setBalooEnabled(true);
258 const QString bookmarsFileName
= bookmarksFile();
259 if (QFileInfo::exists(bookmarsFileName
)) {
260 // Ensure we'll have a clean bookmark file to start
261 QVERIFY(QFile::remove(bookmarsFileName
));
264 qRegisterMetaType
<KItemRangeList
>();
265 qRegisterMetaType
<KItemRange
>();
268 void PlacesItemModelTest::cleanupTestCase()
270 qDeleteAll(m_interfacesMap
);
271 QFile::remove(bookmarksFile());
273 // Remove any previous properties file
274 removeTestUserData();
277 void PlacesItemModelTest::testModelSort()
279 CHECK_PLACES_URLS(initialUrls());
282 void PlacesItemModelTest::testGroups()
284 const auto groups
= m_model
->groups();
286 QCOMPARE(groups
.size(), 6);
288 QCOMPARE(groups
.at(0).first
, 0);
289 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
291 QCOMPARE(groups
.at(1).first
, 3);
292 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
294 QCOMPARE(groups
.at(2).first
, 4);
295 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recently Saved"));
297 QCOMPARE(groups
.at(3).first
, 8);
298 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
300 QCOMPARE(groups
.at(4).first
, 12);
301 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
303 QCOMPARE(groups
.at(5).first
, 14);
304 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
307 void PlacesItemModelTest::testPlaceItem_data()
309 QTest::addColumn
<QUrl
>("url");
310 QTest::addColumn
<bool>("expectedIsHidden");
311 QTest::addColumn
<bool>("expectedIsSystemItem");
312 QTest::addColumn
<QString
>("expectedGroup");
313 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
316 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
319 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
322 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << false << true << QStringLiteral("Recently Saved") << false;
325 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
328 void PlacesItemModelTest::testPlaceItem()
331 QFETCH(bool, expectedIsHidden
);
332 QFETCH(bool, expectedIsSystemItem
);
333 QFETCH(QString
, expectedGroup
);
334 QFETCH(bool, expectedStorageSetupNeeded
);
336 const int index
= indexOf(url
);
337 PlacesItem
*item
= m_model
->placesItem(index
);
338 QCOMPARE(item
->url(), url
);
339 QCOMPARE(item
->isHidden(), expectedIsHidden
);
340 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
341 QCOMPARE(item
->group(), expectedGroup
);
342 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
345 void PlacesItemModelTest::testDeletePlace()
347 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
348 QStringList urls
= initialUrls();
349 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
350 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
352 PlacesItemModel
*model
= new PlacesItemModel();
354 // create a new place
355 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
356 urls
.insert(3, tempUrl
.toLocalFile());
358 // check if the new entry was created
359 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
360 CHECK_PLACES_URLS(urls
);
361 QTRY_COMPARE(model
->count(), m_model
->count());
364 m_model
->deleteItem(3);
366 // make sure that the new item is removed
367 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
368 QTRY_COMPARE(m_model
->count(), 17);
369 CHECK_PLACES_URLS(initialUrls());
370 QTRY_COMPARE(model
->count(), m_model
->count());
373 void PlacesItemModelTest::testTearDownDevice()
375 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
376 int index
= indexOf(mediaUrl
);
377 QVERIFY(index
!= -1);
379 auto ejectAction
= m_model
->ejectAction(index
);
380 QVERIFY(!ejectAction
);
382 auto teardownAction
= m_model
->teardownAction(index
);
383 QVERIFY(teardownAction
);
385 QCOMPARE(m_model
->count(), 17);
387 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
388 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
389 QTRY_COMPARE(m_model
->count(), 16);
390 QCOMPARE(spyItemsRemoved
.count(), 1);
391 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
392 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
393 QCOMPARE(removedRange
.size(), 1);
394 QCOMPARE(removedRange
.first().index
, index
);
395 QCOMPARE(removedRange
.first().count
, 1);
397 QCOMPARE(indexOf(mediaUrl
), -1);
399 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
400 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
401 QTRY_COMPARE(m_model
->count(), 17);
402 QCOMPARE(spyItemsInserted
.count(), 1);
403 index
= indexOf(mediaUrl
);
405 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
406 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
407 QCOMPARE(insertedRange
.size(), 1);
408 QCOMPARE(insertedRange
.first().index
, index
);
409 QCOMPARE(insertedRange
.first().count
, 1);
412 void PlacesItemModelTest::testDefaultViewProperties_data()
414 QTest::addColumn
<QUrl
>("url");
415 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
416 QTest::addColumn
<bool>("expectedPreviewShow");
417 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
420 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
423 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
426 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
429 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
432 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
436 void PlacesItemModelTest::testDefaultViewProperties()
439 QFETCH(DolphinView::Mode
, expectedViewMode
);
440 QFETCH(bool, expectedPreviewShow
);
441 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
443 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
444 QCOMPARE(properties
.viewMode(), expectedViewMode
);
445 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
446 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
449 void PlacesItemModelTest::testClear()
451 QCOMPARE(m_model
->count(), 17);
453 QCOMPARE(m_model
->count(), 0);
454 QCOMPARE(m_model
->hiddenCount(), 0);
456 QTRY_COMPARE(m_model
->count(), 17);
459 void PlacesItemModelTest::testHideItem()
461 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
462 const int index
= indexOf(mediaUrl
);
464 PlacesItem
*item
= m_model
->placesItem(index
);
466 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
467 QList
<QVariant
> spyItemsRemovedArgs
;
468 KItemRangeList removedRange
;
470 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
471 QList
<QVariant
> spyItemsInsertedArgs
;
472 KItemRangeList insertedRange
;
476 item
->setHidden(true);
478 // check if items removed was fired
479 QTRY_COMPARE(m_model
->count(), 16);
480 QCOMPARE(spyItemsRemoved
.count(), 1);
481 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
482 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
483 QCOMPARE(removedRange
.size(), 1);
484 QCOMPARE(removedRange
.first().index
, index
);
485 QCOMPARE(removedRange
.first().count
, 1);
487 // allow model to show hidden items
488 m_model
->setHiddenItemsShown(true);
490 // check if the items inserted was fired
491 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
492 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
493 QCOMPARE(insertedRange
.size(), 1);
494 QCOMPARE(insertedRange
.first().index
, index
);
495 QCOMPARE(insertedRange
.first().count
, 1);
497 // mark item as visible
498 item
= m_model
->placesItem(index
);
499 item
->setHidden(false);
501 // mark model to hide invisible items
502 m_model
->setHiddenItemsShown(true);
504 QTRY_COMPARE(m_model
->count(), 17);
507 void PlacesItemModelTest::testSystemItems()
509 QCOMPARE(m_model
->count(), 17);
510 for (int r
= 0; r
< m_model
->count(); r
++) {
511 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
514 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
516 // create a new entry (non system item)
517 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
519 // check if the new entry was created
520 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
522 // make sure the new place get removed
525 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
526 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
527 QCOMPARE(range
.first().index
, 3);
528 QCOMPARE(range
.first().count
, 1);
529 QVERIFY(!m_model
->placesItem(3)->isSystemItem());
530 QCOMPARE(m_model
->count(), 18);
533 // check if the removal signal is correct
534 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
535 m_model
->deleteItem(3);
536 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
537 args
= itemsRemovedSpy
.takeFirst();
538 range
= args
.at(0).value
<KItemRangeList
>();
539 QCOMPARE(range
.first().index
, 3);
540 QCOMPARE(range
.first().count
, 1);
541 QTRY_COMPARE(m_model
->count(), 17);
543 //cancel removal (it was removed above)
544 cancelPlaceRemoval(3);
547 void PlacesItemModelTest::testEditBookmark()
549 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
550 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
552 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
554 // make sure that the new item will be removed later
557 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
560 m_model
->item(3)->setText(QStringLiteral("Renamed place"));
563 // check if the correct signal was fired
564 QTRY_COMPARE(itemsChangedSply
.count(), 1);
565 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
566 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
567 QCOMPARE(range
.first().index
, 3);
568 QCOMPARE(range
.first().count
, 1);
569 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
570 QCOMPARE(roles
.size(), 1);
571 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
572 QCOMPARE(m_model
->item(3)->text(), QStringLiteral("Renamed place"));
574 // check if the item was updated in the other model
575 QTRY_COMPARE(other
->item(3)->text(), QStringLiteral("Renamed place"));
578 void PlacesItemModelTest::testEditAfterCreation()
580 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
581 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
583 // create a new place
584 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
585 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
587 PlacesItemModel
*model
= new PlacesItemModel();
588 QTRY_COMPARE(model
->count(), m_model
->count());
590 // make sure that the new item will be removed later
594 PlacesItem
*item
= m_model
->placesItem(3);
595 item
->setText(QStringLiteral("Renamed place"));
598 // check if the second model got the changes
599 QTRY_COMPARE(model
->count(), m_model
->count());
600 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
601 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
602 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
603 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
604 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
607 void PlacesItemModelTest::testEditMetadata()
609 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
610 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
612 // create a new place
613 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
614 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
616 // check if the new entry was created
617 PlacesItemModel
*model
= new PlacesItemModel();
618 QTRY_COMPARE(model
->count(), m_model
->count());
620 // make sure that the new item will be removed later
623 // modify place metadata
624 PlacesItem
*item
= m_model
->placesItem(3);
625 item
->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
628 // check if the place was modified in both models
629 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
630 KAboutData::applicationData().componentName());
631 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
632 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
633 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
634 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
635 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
638 void PlacesItemModelTest::testRefresh()
640 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
641 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
643 // create a new place
644 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
645 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
647 PlacesItemModel
*model
= new PlacesItemModel();
648 QTRY_COMPARE(model
->count(), m_model
->count());
650 // make sure that the new item will be removed later
653 PlacesItem
*item
= m_model
->placesItem(3);
654 PlacesItem
*sameItem
= model
->placesItem(3);
655 QCOMPARE(item
->text(), sameItem
->text());
658 item
->setText(QStringLiteral("Renamed place"));
660 // item from another model is not affected at the moment
661 QVERIFY(item
->text() != sameItem
->text());
666 // item must be equal
667 QTRY_COMPARE(item
->text(), sameItem
->text());
670 void PlacesItemModelTest::testIcons_data()
672 QTest::addColumn
<QUrl
>("url");
673 QTest::addColumn
<QString
>("expectedIconName");
676 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
679 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
682 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << QStringLiteral("view-calendar-month");
685 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
688 void PlacesItemModelTest::testIcons()
691 QFETCH(QString
, expectedIconName
);
693 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
694 QCOMPARE(item
->icon(), expectedIconName
);
696 for (int r
= 0; r
< m_model
->count(); r
++) {
697 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
701 void PlacesItemModelTest::testDragAndDrop()
703 QList
<QVariant
> args
;
704 KItemRangeList range
;
705 QStringList urls
= initialUrls();
706 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
707 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
709 CHECK_PLACES_URLS(initialUrls());
710 // Move the KDE_ROOT_PATH at the end of the places list will case it to be moved to the end of the places group
711 QMimeData
*dropData
= createMimeData(QList
<int>() << 1);
712 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
716 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
717 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
719 // remove item from actual position
720 args
= itemsRemovedSpy
.takeFirst();
721 range
= args
.at(0).value
<KItemRangeList
>();
722 QCOMPARE(range
.size(), 1);
723 QCOMPARE(range
.at(0).count
, 1);
724 QCOMPARE(range
.at(0).index
, 1);
726 // insert intem in his group
727 args
= itemsInsertedSpy
.takeFirst();
728 range
= args
.at(0).value
<KItemRangeList
>();
729 QCOMPARE(range
.size(), 1);
730 QCOMPARE(range
.at(0).count
, 1);
731 QCOMPARE(range
.at(0).index
, 2);
733 CHECK_PLACES_URLS(urls
);
735 itemsInsertedSpy
.clear();
736 itemsRemovedSpy
.clear();
738 // Move the KDE_ROOT_PATH to his original position
739 dropData
= createMimeData(QList
<int>() << 2);
740 m_model
->dropMimeDataBefore(1, dropData
);
744 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
745 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
747 // remove item from actual position
748 args
= itemsRemovedSpy
.takeFirst();
749 range
= args
.at(0).value
<KItemRangeList
>();
750 QCOMPARE(range
.size(), 1);
751 QCOMPARE(range
.at(0).count
, 1);
752 QCOMPARE(range
.at(0).index
, 2);
754 // insert intem in the requested position
755 args
= itemsInsertedSpy
.takeFirst();
756 range
= args
.at(0).value
<KItemRangeList
>();
757 QCOMPARE(range
.size(), 1);
758 QCOMPARE(range
.at(0).count
, 1);
759 QCOMPARE(range
.at(0).index
, 1);
761 CHECK_PLACES_URLS(urls
);
764 void PlacesItemModelTest::testHideDevices()
766 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
767 QStringList urls
= initialUrls();
769 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
770 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
771 QTRY_COMPARE(itemsRemoved
.count(), 3);
773 // remove removable-devices
774 urls
.removeOne(QStringLiteral("/media/floppy0"));
775 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
776 urls
.removeOne(QStringLiteral("/media/cdrom"));
778 // check if the correct urls was removed
779 CHECK_PLACES_URLS(urls
);
782 m_model
= new PlacesItemModel();
783 QTRY_COMPARE(m_model
->count(), urls
.count());
784 CHECK_PLACES_URLS(urls
);
787 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
788 urls
= initialUrls();
789 QTRY_COMPARE(m_model
->count(), urls
.count());
790 CHECK_PLACES_URLS(urls
);
793 void PlacesItemModelTest::testDuplicatedEntries()
795 QStringList urls
= initialUrls();
796 // create a duplicated entry on bookmark
797 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
798 KBookmarkGroup root
= bookmarkManager
->root();
799 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
801 const QString id
= QUuid::createUuid().toString();
802 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
803 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
804 bookmarkManager
->emitChanged(bookmarkManager
->root());
806 PlacesItemModel
*newModel
= new PlacesItemModel();
807 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
808 QTRY_COMPARE(urls
, placesUrls(newModel
));
812 void PlacesItemModelTest::renameAfterCreation()
814 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
815 QStringList urls
= initialUrls();
816 PlacesItemModel
*model
= new PlacesItemModel();
818 CHECK_PLACES_URLS(urls
);
819 QTRY_COMPARE(model
->count(), m_model
->count());
821 // create a new place
822 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
823 urls
.insert(3, tempUrl
.toLocalFile());
825 // make sure that the new item will be removed later
828 CHECK_PLACES_URLS(urls
);
829 QCOMPARE(model
->count(), m_model
->count());
833 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
835 PlacesItem
*item
= m_model
->placesItem(3);
836 item
->setText(QStringLiteral("New Temporary Dir"));
837 item
->setUrl(item
->url());
838 item
->setIcon(item
->icon());
841 QTRY_COMPARE(changedSpy
.count(), 1);
843 // check if the place was modified in both models
844 QTRY_COMPARE(m_model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
845 QTRY_COMPARE(model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
848 QTEST_MAIN(PlacesItemModelTest
)
850 #include "placesitemmodeltest.moc"