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
;
89 void setBalooEnabled(bool enabled
);
90 int indexOf(const QUrl
&url
);
91 QDBusInterface
*fakeManager();
92 QDBusInterface
*fakeDevice(const QString
&udi
);
93 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
94 QStringList
initialUrls() const;
95 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
96 void removePlaceAfter(int index
);
97 void cancelPlaceRemoval(int index
);
98 void removeTestUserData();
99 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
102 #define CHECK_PLACES_URLS(urls) \
104 QStringList places = placesUrls(); \
105 if (places != urls) { \
106 qWarning() << "Expected:" << urls; \
107 qWarning() << "Got:" << places; \
108 QCOMPARE(places, urls); \
112 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
114 KConfig
config(QStringLiteral("baloofilerc"));
115 KConfigGroup basicSettings
= config
.group("Basic Settings");
116 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
120 int PlacesItemModelTest::indexOf(const QUrl
&url
)
122 for (int r
= 0; r
< m_model
->count(); r
++) {
123 if (m_model
->placesItem(r
)->url() == url
) {
130 QDBusInterface
*PlacesItemModelTest::fakeManager()
132 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
135 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
137 if (m_interfacesMap
.contains(udi
)) {
138 return m_interfacesMap
[udi
];
141 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
142 m_interfacesMap
[udi
] = iface
;
147 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
154 for (int row
= 0; row
< model
->count(); ++row
) {
155 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
160 QStringList
PlacesItemModelTest::initialUrls() const
162 static QStringList urls
;
163 if (urls
.isEmpty()) {
164 urls
<< QDir::homePath() << QStringLiteral(KDE_ROOT_PATH
) << QStringLiteral("trash:/")
165 << QStringLiteral("remote:/")
166 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday") << QStringLiteral("timeline:/thismonth") << QStringLiteral("timeline:/lastmonth")
167 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
168 << QStringLiteral("/media/nfs") << QStringLiteral("/foreign")
169 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
174 void PlacesItemModelTest::createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
)
176 m_model
->createPlacesItem(text
, url
, icon
);
179 void PlacesItemModelTest::removePlaceAfter(int index
)
181 m_tobeRemoved
.insert(index
);
184 void PlacesItemModelTest::cancelPlaceRemoval(int index
)
186 m_tobeRemoved
.remove(index
);
189 void PlacesItemModelTest::removeTestUserData()
191 // user hardcoded path to avoid removal of any user personal data
192 QDir
dir(QStringLiteral("/home/renato/.qttest/share/placesitemmodeltest"));
194 QVERIFY(dir
.removeRecursively());
198 QMimeData
*PlacesItemModelTest::createMimeData(const QList
<int> &indexes
) const
201 QDataStream
stream(&itemData
, QIODevice::WriteOnly
);
204 for (int index
: indexes
) {
205 const QUrl itemUrl
= m_model
->placesItem(index
)->url();
206 if (itemUrl
.isValid()) {
212 QMimeData
* mimeData
= new QMimeData();
213 mimeData
->setUrls(urls
);
214 // copied from PlacesItemModel::internalMimeType()
215 const QString internalMimeType
= "application/x-dolphinplacesmodel-" +
216 QString::number((qptrdiff
)m_model
);
217 mimeData
->setData(internalMimeType
, itemData
);
221 void PlacesItemModelTest::init()
223 m_model
= new PlacesItemModel();
224 // WORKAROUND: need to wait for bookmark to load, check: PlacesItemModel::updateBookmarks
226 QCOMPARE(m_model
->count(), 17);
229 void PlacesItemModelTest::cleanup()
231 const auto tobeRemoved
= m_tobeRemoved
;
232 for (const int i
: tobeRemoved
) {
233 int before
= m_model
->count();
234 m_model
->deleteItem(i
);
235 QTRY_COMPARE(m_model
->count(), before
- 1);
237 m_tobeRemoved
.clear();
240 removeTestUserData();
243 void PlacesItemModelTest::initTestCase()
245 QStandardPaths::setTestModeEnabled(true);
246 // remove test user data
247 removeTestUserData();
249 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
250 QVERIFY(!fakeHw
.isEmpty());
251 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
253 setBalooEnabled(true);
254 const QString bookmarsFileName
= bookmarksFile();
255 if (QFileInfo::exists(bookmarsFileName
)) {
256 // Ensure we'll have a clean bookmark file to start
257 QVERIFY(QFile::remove(bookmarsFileName
));
260 qRegisterMetaType
<KItemRangeList
>();
261 qRegisterMetaType
<KItemRange
>();
264 void PlacesItemModelTest::cleanupTestCase()
266 qDeleteAll(m_interfacesMap
);
267 QFile::remove(bookmarksFile());
269 // Remove any previous properties file
270 removeTestUserData();
273 void PlacesItemModelTest::testModelSort()
275 CHECK_PLACES_URLS(initialUrls());
278 void PlacesItemModelTest::testGroups()
280 const auto groups
= m_model
->groups();
282 QCOMPARE(groups
.size(), 6);
284 QCOMPARE(groups
.at(0).first
, 0);
285 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
287 QCOMPARE(groups
.at(1).first
, 3);
288 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
290 QCOMPARE(groups
.at(2).first
, 4);
291 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recently Saved"));
293 QCOMPARE(groups
.at(3).first
, 8);
294 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
296 QCOMPARE(groups
.at(4).first
, 12);
297 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
299 QCOMPARE(groups
.at(5).first
, 14);
300 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
303 void PlacesItemModelTest::testPlaceItem_data()
305 QTest::addColumn
<QUrl
>("url");
306 QTest::addColumn
<bool>("expectedIsHidden");
307 QTest::addColumn
<bool>("expectedIsSystemItem");
308 QTest::addColumn
<QString
>("expectedGroup");
309 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
312 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
315 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
318 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << false << true << QStringLiteral("Recently Saved") << false;
321 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
324 void PlacesItemModelTest::testPlaceItem()
327 QFETCH(bool, expectedIsHidden
);
328 QFETCH(bool, expectedIsSystemItem
);
329 QFETCH(QString
, expectedGroup
);
330 QFETCH(bool, expectedStorageSetupNeeded
);
332 const int index
= indexOf(url
);
333 PlacesItem
*item
= m_model
->placesItem(index
);
334 QCOMPARE(item
->url(), url
);
335 QCOMPARE(item
->isHidden(), expectedIsHidden
);
336 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
337 QCOMPARE(item
->group(), expectedGroup
);
338 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
341 void PlacesItemModelTest::testDeletePlace()
343 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
344 QStringList urls
= initialUrls();
345 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
346 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
348 PlacesItemModel
*model
= new PlacesItemModel();
350 // create a new place
351 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
352 urls
.insert(3, tempUrl
.toLocalFile());
354 // check if the new entry was created
355 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
356 CHECK_PLACES_URLS(urls
);
357 QTRY_COMPARE(model
->count(), m_model
->count());
360 m_model
->deleteItem(3);
362 // make sure that the new item is removed
363 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
364 QTRY_COMPARE(m_model
->count(), 17);
365 CHECK_PLACES_URLS(initialUrls());
366 QTRY_COMPARE(model
->count(), m_model
->count());
369 void PlacesItemModelTest::testTearDownDevice()
371 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
372 int index
= indexOf(mediaUrl
);
373 QVERIFY(index
!= -1);
375 auto ejectAction
= m_model
->ejectAction(index
);
376 QVERIFY(!ejectAction
);
378 auto teardownAction
= m_model
->teardownAction(index
);
379 QVERIFY(teardownAction
);
381 QCOMPARE(m_model
->count(), 17);
383 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
384 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
385 QTRY_COMPARE(m_model
->count(), 16);
386 QCOMPARE(spyItemsRemoved
.count(), 1);
387 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
388 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
389 QCOMPARE(removedRange
.size(), 1);
390 QCOMPARE(removedRange
.first().index
, index
);
391 QCOMPARE(removedRange
.first().count
, 1);
393 QCOMPARE(indexOf(mediaUrl
), -1);
395 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
396 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
397 QTRY_COMPARE(m_model
->count(), 17);
398 QCOMPARE(spyItemsInserted
.count(), 1);
399 index
= indexOf(mediaUrl
);
401 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
402 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
403 QCOMPARE(insertedRange
.size(), 1);
404 QCOMPARE(insertedRange
.first().index
, index
);
405 QCOMPARE(insertedRange
.first().count
, 1);
408 void PlacesItemModelTest::testDefaultViewProperties_data()
410 QTest::addColumn
<QUrl
>("url");
411 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
412 QTest::addColumn
<bool>("expectedPreviewShow");
413 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
416 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
419 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
422 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
425 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
428 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
432 void PlacesItemModelTest::testDefaultViewProperties()
435 QFETCH(DolphinView::Mode
, expectedViewMode
);
436 QFETCH(bool, expectedPreviewShow
);
437 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
439 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
440 QCOMPARE(properties
.viewMode(), expectedViewMode
);
441 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
442 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
445 void PlacesItemModelTest::testClear()
447 QCOMPARE(m_model
->count(), 17);
449 QCOMPARE(m_model
->count(), 0);
450 QCOMPARE(m_model
->hiddenCount(), 0);
452 QTRY_COMPARE(m_model
->count(), 17);
455 void PlacesItemModelTest::testHideItem()
457 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
458 const int index
= indexOf(mediaUrl
);
460 PlacesItem
*item
= m_model
->placesItem(index
);
462 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
463 QList
<QVariant
> spyItemsRemovedArgs
;
464 KItemRangeList removedRange
;
466 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
467 QList
<QVariant
> spyItemsInsertedArgs
;
468 KItemRangeList insertedRange
;
472 item
->setHidden(true);
474 // check if items removed was fired
475 QTRY_COMPARE(m_model
->count(), 16);
476 QCOMPARE(spyItemsRemoved
.count(), 1);
477 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
478 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
479 QCOMPARE(removedRange
.size(), 1);
480 QCOMPARE(removedRange
.first().index
, index
);
481 QCOMPARE(removedRange
.first().count
, 1);
483 // allow model to show hidden items
484 m_model
->setHiddenItemsShown(true);
486 // check if the items inserted was fired
487 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
488 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
489 QCOMPARE(insertedRange
.size(), 1);
490 QCOMPARE(insertedRange
.first().index
, index
);
491 QCOMPARE(insertedRange
.first().count
, 1);
493 // mark item as visible
494 item
= m_model
->placesItem(index
);
495 item
->setHidden(false);
497 // mark model to hide invisible items
498 m_model
->setHiddenItemsShown(true);
500 QTRY_COMPARE(m_model
->count(), 17);
503 void PlacesItemModelTest::testSystemItems()
505 QCOMPARE(m_model
->count(), 17);
506 for (int r
= 0; r
< m_model
->count(); r
++) {
507 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
510 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
512 // create a new entry (non system item)
513 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
515 // check if the new entry was created
516 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
518 // make sure the new place get removed
521 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
522 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
523 QCOMPARE(range
.first().index
, 3);
524 QCOMPARE(range
.first().count
, 1);
525 QVERIFY(!m_model
->placesItem(3)->isSystemItem());
526 QCOMPARE(m_model
->count(), 18);
529 // check if the removal signal is correct
530 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
531 m_model
->deleteItem(3);
532 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
533 args
= itemsRemovedSpy
.takeFirst();
534 range
= args
.at(0).value
<KItemRangeList
>();
535 QCOMPARE(range
.first().index
, 3);
536 QCOMPARE(range
.first().count
, 1);
537 QTRY_COMPARE(m_model
->count(), 17);
539 //cancel removal (it was removed above)
540 cancelPlaceRemoval(3);
543 void PlacesItemModelTest::testEditBookmark()
545 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
547 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
549 // make sure that the new item will be removed later
552 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
555 m_model
->item(3)->setText(QStringLiteral("Renamed place"));
558 // check if the correct signal was fired
559 QTRY_COMPARE(itemsChangedSply
.count(), 1);
560 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
561 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
562 QCOMPARE(range
.first().index
, 3);
563 QCOMPARE(range
.first().count
, 1);
564 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
565 QCOMPARE(roles
.size(), 1);
566 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
567 QCOMPARE(m_model
->item(3)->text(), QStringLiteral("Renamed place"));
569 // check if the item was updated in the other model
570 QTRY_COMPARE(other
->item(3)->text(), QStringLiteral("Renamed place"));
573 void PlacesItemModelTest::testEditAfterCreation()
575 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
576 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
578 // create a new place
579 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
580 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
582 PlacesItemModel
*model
= new PlacesItemModel();
583 QTRY_COMPARE(model
->count(), m_model
->count());
585 // make sure that the new item will be removed later
589 PlacesItem
*item
= m_model
->placesItem(3);
590 item
->setText(QStringLiteral("Renamed place"));
593 // check if the second model got the changes
594 QTRY_COMPARE(model
->count(), m_model
->count());
595 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
596 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
597 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
598 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
599 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
602 void PlacesItemModelTest::testEditMetadata()
604 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
605 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
607 // create a new place
608 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
609 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
611 // check if the new entry was created
612 PlacesItemModel
*model
= new PlacesItemModel();
613 QTRY_COMPARE(model
->count(), m_model
->count());
615 // make sure that the new item will be removed later
618 // modify place metadata
619 PlacesItem
*item
= m_model
->placesItem(3);
620 item
->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
623 // check if the place was modified in both models
624 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
625 KAboutData::applicationData().componentName());
626 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
627 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
628 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
629 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
630 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
633 void PlacesItemModelTest::testRefresh()
635 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
636 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
638 // create a new place
639 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
640 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
642 PlacesItemModel
*model
= new PlacesItemModel();
643 QTRY_COMPARE(model
->count(), m_model
->count());
645 // make sure that the new item will be removed later
648 PlacesItem
*item
= m_model
->placesItem(3);
649 PlacesItem
*sameItem
= model
->placesItem(3);
650 QCOMPARE(item
->text(), sameItem
->text());
653 item
->setText(QStringLiteral("Renamed place"));
655 // item from another model is not affected at the moment
656 QVERIFY(item
->text() != sameItem
->text());
661 // item must be equal
662 QTRY_COMPARE(item
->text(), sameItem
->text());
665 void PlacesItemModelTest::testIcons_data()
667 QTest::addColumn
<QUrl
>("url");
668 QTest::addColumn
<QString
>("expectedIconName");
671 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
674 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
677 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << QStringLiteral("view-calendar-month");
680 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
683 void PlacesItemModelTest::testIcons()
686 QFETCH(QString
, expectedIconName
);
688 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
689 QCOMPARE(item
->icon(), expectedIconName
);
691 for (int r
= 0; r
< m_model
->count(); r
++) {
692 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
696 void PlacesItemModelTest::testDragAndDrop()
698 QList
<QVariant
> args
;
699 KItemRangeList range
;
700 QStringList urls
= initialUrls();
701 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
702 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
704 CHECK_PLACES_URLS(initialUrls());
705 // 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
706 QMimeData
*dropData
= createMimeData(QList
<int>() << 1);
707 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
711 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
712 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
714 // remove item from actual position
715 args
= itemsRemovedSpy
.takeFirst();
716 range
= args
.at(0).value
<KItemRangeList
>();
717 QCOMPARE(range
.size(), 1);
718 QCOMPARE(range
.at(0).count
, 1);
719 QCOMPARE(range
.at(0).index
, 1);
721 // insert intem in his group
722 args
= itemsInsertedSpy
.takeFirst();
723 range
= args
.at(0).value
<KItemRangeList
>();
724 QCOMPARE(range
.size(), 1);
725 QCOMPARE(range
.at(0).count
, 1);
726 QCOMPARE(range
.at(0).index
, 2);
728 CHECK_PLACES_URLS(urls
);
730 itemsInsertedSpy
.clear();
731 itemsRemovedSpy
.clear();
733 // Move the KDE_ROOT_PATH to his original position
734 dropData
= createMimeData(QList
<int>() << 2);
735 m_model
->dropMimeDataBefore(1, dropData
);
739 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
740 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
742 // remove item from actual position
743 args
= itemsRemovedSpy
.takeFirst();
744 range
= args
.at(0).value
<KItemRangeList
>();
745 QCOMPARE(range
.size(), 1);
746 QCOMPARE(range
.at(0).count
, 1);
747 QCOMPARE(range
.at(0).index
, 2);
749 // insert intem in the requested position
750 args
= itemsInsertedSpy
.takeFirst();
751 range
= args
.at(0).value
<KItemRangeList
>();
752 QCOMPARE(range
.size(), 1);
753 QCOMPARE(range
.at(0).count
, 1);
754 QCOMPARE(range
.at(0).index
, 1);
756 CHECK_PLACES_URLS(urls
);
759 void PlacesItemModelTest::testHideDevices()
761 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
762 QStringList urls
= initialUrls();
764 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
765 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
766 QTRY_COMPARE(itemsRemoved
.count(), 3);
768 // remove removable-devices
769 urls
.removeOne(QStringLiteral("/media/floppy0"));
770 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
771 urls
.removeOne(QStringLiteral("/media/cdrom"));
773 // check if the correct urls was removed
774 CHECK_PLACES_URLS(urls
);
777 m_model
= new PlacesItemModel();
778 QTRY_COMPARE(m_model
->count(), urls
.count());
779 CHECK_PLACES_URLS(urls
);
782 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
783 urls
= initialUrls();
784 QTRY_COMPARE(m_model
->count(), urls
.count());
785 CHECK_PLACES_URLS(urls
);
788 void PlacesItemModelTest::testDuplicatedEntries()
790 QStringList urls
= initialUrls();
791 // create a duplicated entry on bookmark
792 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
793 KBookmarkGroup root
= bookmarkManager
->root();
794 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
796 const QString id
= QUuid::createUuid().toString();
797 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
798 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
799 bookmarkManager
->emitChanged(bookmarkManager
->root());
801 PlacesItemModel
*newModel
= new PlacesItemModel();
802 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
803 QTRY_COMPARE(urls
, placesUrls(newModel
));
807 void PlacesItemModelTest::renameAfterCreation()
809 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
810 QStringList urls
= initialUrls();
811 PlacesItemModel
*model
= new PlacesItemModel();
813 CHECK_PLACES_URLS(urls
);
814 QTRY_COMPARE(model
->count(), m_model
->count());
816 // create a new place
817 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
818 urls
.insert(3, tempUrl
.toLocalFile());
820 // make sure that the new item will be removed later
823 CHECK_PLACES_URLS(urls
);
824 QCOMPARE(model
->count(), m_model
->count());
828 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
830 PlacesItem
*item
= m_model
->placesItem(3);
831 item
->setText(QStringLiteral("New Temporary Dir"));
832 item
->setUrl(item
->url());
833 item
->setIcon(item
->icon());
836 QTRY_COMPARE(changedSpy
.count(), 1);
838 // check if the place was modified in both models
839 QTRY_COMPARE(m_model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
840 QTRY_COMPARE(model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
843 QTEST_MAIN(PlacesItemModelTest
)
845 #include "placesitemmodeltest.moc"