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;
90 void setBalooEnabled(bool enabled
);
91 int indexOf(const QUrl
&url
);
92 QDBusInterface
*fakeManager();
93 QDBusInterface
*fakeDevice(const QString
&udi
);
94 QStringList
placesUrls(PlacesItemModel
*model
= nullptr) const;
95 QStringList
initialUrls() const;
96 void createPlaceItem(const QString
&text
, const QUrl
&url
, const QString
&icon
);
97 void removePlaceAfter(int index
);
98 void cancelPlaceRemoval(int index
);
99 void removeTestUserData();
100 QMimeData
*createMimeData(const QList
<int> &indexes
) const;
103 #define CHECK_PLACES_URLS(urls) \
105 QStringList places = placesUrls(); \
106 if (places != urls) { \
107 qWarning() << "Expected:" << urls; \
108 qWarning() << "Got:" << places; \
109 QCOMPARE(places, urls); \
113 void PlacesItemModelTest::setBalooEnabled(bool enabled
)
115 KConfig
config(QStringLiteral("baloofilerc"));
116 KConfigGroup basicSettings
= config
.group("Basic Settings");
117 basicSettings
.writeEntry("Indexing-Enabled", enabled
);
121 int PlacesItemModelTest::indexOf(const QUrl
&url
)
123 for (int r
= 0; r
< m_model
->count(); r
++) {
124 if (m_model
->placesItem(r
)->url() == url
) {
131 QDBusInterface
*PlacesItemModelTest::fakeManager()
133 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
136 QDBusInterface
*PlacesItemModelTest::fakeDevice(const QString
&udi
)
138 if (m_interfacesMap
.contains(udi
)) {
139 return m_interfacesMap
[udi
];
142 QDBusInterface
*iface
= new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi
);
143 m_interfacesMap
[udi
] = iface
;
148 QStringList
PlacesItemModelTest::placesUrls(PlacesItemModel
*model
) const
155 for (int row
= 0; row
< model
->count(); ++row
) {
156 urls
<< model
->placesItem(row
)->url().toDisplayString(QUrl::PreferLocalFile
);
161 QStringList
PlacesItemModelTest::initialUrls() const
163 static QStringList urls
;
164 if (urls
.isEmpty()) {
165 urls
<< QDir::homePath()
166 << QDir::homePath() + QStringLiteral("/Desktop")
167 << QDir::homePath() + QStringLiteral("/Downloads")
168 << QStringLiteral(KDE_ROOT_PATH
) << QStringLiteral("trash:/")
169 << QStringLiteral("remote:/")
170 << QStringLiteral("/media/nfs")
171 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday")
172 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
173 << 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(), m_expectedModelCount
);
234 void PlacesItemModelTest::cleanup()
236 const auto tobeRemoved
= m_tobeRemoved
;
237 for (const int i
: tobeRemoved
) {
238 int before
= m_model
->count();
239 m_model
->deleteItem(i
);
240 QTRY_COMPARE(m_model
->count(), before
- 1);
242 m_tobeRemoved
.clear();
245 removeTestUserData();
248 void PlacesItemModelTest::initTestCase()
250 QStandardPaths::setTestModeEnabled(true);
251 // remove test user data
252 removeTestUserData();
254 const QString fakeHw
= QFINDTESTDATA("data/fakecomputer.xml");
255 QVERIFY(!fakeHw
.isEmpty());
256 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw
));
258 setBalooEnabled(true);
259 const QString bookmarsFileName
= bookmarksFile();
260 if (QFileInfo::exists(bookmarsFileName
)) {
261 // Ensure we'll have a clean bookmark file to start
262 QVERIFY(QFile::remove(bookmarsFileName
));
265 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation
)).exists()) {
266 m_expectedModelCount
++;
269 if (QDir(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation
)).exists()) {
270 m_expectedModelCount
++;
273 qRegisterMetaType
<KItemRangeList
>();
274 qRegisterMetaType
<KItemRange
>();
277 void PlacesItemModelTest::cleanupTestCase()
279 qDeleteAll(m_interfacesMap
);
280 QFile::remove(bookmarksFile());
282 // Remove any previous properties file
283 removeTestUserData();
286 void PlacesItemModelTest::testModelSort()
288 CHECK_PLACES_URLS(initialUrls());
291 void PlacesItemModelTest::testGroups()
293 const auto groups
= m_model
->groups();
296 QCOMPARE(groups
.size(), 6);
298 QCOMPARE(groups
.at(0).first
, 0);
299 QCOMPARE(groups
.at(0).second
.toString(), QStringLiteral("Places"));
301 QCOMPARE(groups
.at(1).first
, 5);
302 QCOMPARE(groups
.at(1).second
.toString(), QStringLiteral("Remote"));
304 QCOMPARE(groups
.at(2).first
, 7);
305 QCOMPARE(groups
.at(2).second
.toString(), QStringLiteral("Recently Saved"));
307 QCOMPARE(groups
.at(3).first
, 9);
308 QCOMPARE(groups
.at(3).second
.toString(), QStringLiteral("Search For"));
310 QCOMPARE(groups
.at(4).first
, 13);
311 QCOMPARE(groups
.at(4).second
.toString(), QStringLiteral("Devices"));
313 QCOMPARE(groups
.at(5).first
, 14);
314 QCOMPARE(groups
.at(5).second
.toString(), QStringLiteral("Removable Devices"));
317 void PlacesItemModelTest::testPlaceItem_data()
319 QTest::addColumn
<QUrl
>("url");
320 QTest::addColumn
<bool>("expectedIsHidden");
321 QTest::addColumn
<bool>("expectedIsSystemItem");
322 QTest::addColumn
<QString
>("expectedGroup");
323 QTest::addColumn
<bool>("expectedStorageSetupNeeded");
326 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
329 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
332 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << false << true << QStringLiteral("Recently Saved") << false;
335 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
338 void PlacesItemModelTest::testPlaceItem()
341 QFETCH(bool, expectedIsHidden
);
342 QFETCH(bool, expectedIsSystemItem
);
343 QFETCH(QString
, expectedGroup
);
344 QFETCH(bool, expectedStorageSetupNeeded
);
346 const int index
= indexOf(url
);
347 PlacesItem
*item
= m_model
->placesItem(index
);
348 QCOMPARE(item
->url(), url
);
349 QCOMPARE(item
->isHidden(), expectedIsHidden
);
350 QCOMPARE(item
->isSystemItem(), expectedIsSystemItem
);
351 QCOMPARE(item
->group(), expectedGroup
);
352 QCOMPARE(item
->storageSetupNeeded(), expectedStorageSetupNeeded
);
355 void PlacesItemModelTest::testDeletePlace()
357 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
358 QStringList urls
= initialUrls();
359 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
360 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
362 PlacesItemModel
*model
= new PlacesItemModel();
364 // create a new place
365 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
366 urls
.insert(5, tempUrl
.toLocalFile());
368 // check if the new entry was created
369 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
370 CHECK_PLACES_URLS(urls
);
371 QTRY_COMPARE(model
->count(), m_model
->count());
374 m_model
->deleteItem(5);
376 // make sure that the new item is removed
377 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
378 QTRY_COMPARE(m_model
->count(), 17);
379 CHECK_PLACES_URLS(initialUrls());
380 QTRY_COMPARE(model
->count(), m_model
->count());
383 void PlacesItemModelTest::testTearDownDevice()
385 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
386 int index
= indexOf(mediaUrl
);
387 QVERIFY(index
!= -1);
389 auto ejectAction
= m_model
->ejectAction(index
);
390 QVERIFY(!ejectAction
);
392 auto teardownAction
= m_model
->teardownAction(index
);
393 QVERIFY(teardownAction
);
395 QCOMPARE(m_model
->count(), 17);
397 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
398 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
399 QTRY_COMPARE(m_model
->count(), 16);
400 QCOMPARE(spyItemsRemoved
.count(), 1);
401 const QList
<QVariant
> spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
402 const KItemRangeList removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
403 QCOMPARE(removedRange
.size(), 1);
404 QCOMPARE(removedRange
.first().index
, index
);
405 QCOMPARE(removedRange
.first().count
, 1);
407 QCOMPARE(indexOf(mediaUrl
), -1);
409 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
410 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
411 QTRY_COMPARE(m_model
->count(), 17);
412 QCOMPARE(spyItemsInserted
.count(), 1);
413 index
= indexOf(mediaUrl
);
415 const QList
<QVariant
> args
= spyItemsInserted
.takeFirst();
416 const KItemRangeList insertedRange
= args
.at(0).value
<KItemRangeList
>();
417 QCOMPARE(insertedRange
.size(), 1);
418 QCOMPARE(insertedRange
.first().index
, index
);
419 QCOMPARE(insertedRange
.first().count
, 1);
422 void PlacesItemModelTest::testDefaultViewProperties_data()
424 QTest::addColumn
<QUrl
>("url");
425 QTest::addColumn
<DolphinView::Mode
>("expectedViewMode");
426 QTest::addColumn
<bool>("expectedPreviewShow");
427 QTest::addColumn
<QList
<QByteArray
> >("expectedVisibleRole");
430 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
433 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "path"});
436 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView
<< false << QList
<QByteArray
>({"text", "artist", "album"});
439 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << DolphinView::DetailsView
<< true << QList
<QByteArray
>({"text", "modificationtime"});
442 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView
<< true << QList
<QByteArray
>({"text"});
446 void PlacesItemModelTest::testDefaultViewProperties()
449 QFETCH(DolphinView::Mode
, expectedViewMode
);
450 QFETCH(bool, expectedPreviewShow
);
451 QFETCH(QList
<QByteArray
>, expectedVisibleRole
);
453 ViewProperties
properties(KFilePlacesModel::convertedUrl(url
));
454 QCOMPARE(properties
.viewMode(), expectedViewMode
);
455 QCOMPARE(properties
.previewsShown(), expectedPreviewShow
);
456 QCOMPARE(properties
.visibleRoles(), expectedVisibleRole
);
459 void PlacesItemModelTest::testClear()
461 QCOMPARE(m_model
->count(), 17);
463 QCOMPARE(m_model
->count(), 0);
464 QCOMPARE(m_model
->hiddenCount(), 0);
466 QTRY_COMPARE(m_model
->count(), 17);
469 void PlacesItemModelTest::testHideItem()
471 const QUrl mediaUrl
= QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
472 const int index
= indexOf(mediaUrl
);
474 PlacesItem
*item
= m_model
->placesItem(index
);
476 QSignalSpy
spyItemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
477 QList
<QVariant
> spyItemsRemovedArgs
;
478 KItemRangeList removedRange
;
480 QSignalSpy
spyItemsInserted(m_model
, &PlacesItemModel::itemsInserted
);
481 QList
<QVariant
> spyItemsInsertedArgs
;
482 KItemRangeList insertedRange
;
486 item
->setHidden(true);
488 // check if items removed was fired
489 QTRY_COMPARE(m_model
->count(), 16);
490 QCOMPARE(spyItemsRemoved
.count(), 1);
491 spyItemsRemovedArgs
= spyItemsRemoved
.takeFirst();
492 removedRange
= spyItemsRemovedArgs
.at(0).value
<KItemRangeList
>();
493 QCOMPARE(removedRange
.size(), 1);
494 QCOMPARE(removedRange
.first().index
, index
);
495 QCOMPARE(removedRange
.first().count
, 1);
497 // allow model to show hidden items
498 m_model
->setHiddenItemsShown(true);
500 // check if the items inserted was fired
501 spyItemsInsertedArgs
= spyItemsInserted
.takeFirst();
502 insertedRange
= spyItemsInsertedArgs
.at(0).value
<KItemRangeList
>();
503 QCOMPARE(insertedRange
.size(), 1);
504 QCOMPARE(insertedRange
.first().index
, index
);
505 QCOMPARE(insertedRange
.first().count
, 1);
507 // mark item as visible
508 item
= m_model
->placesItem(index
);
509 item
->setHidden(false);
511 // mark model to hide invisible items
512 m_model
->setHiddenItemsShown(true);
514 QTRY_COMPARE(m_model
->count(), 17);
517 void PlacesItemModelTest::testSystemItems()
519 QCOMPARE(m_model
->count(), 17);
520 for (int r
= 0; r
< m_model
->count(); r
++) {
521 QCOMPARE(m_model
->placesItem(r
)->isSystemItem(), !m_model
->placesItem(r
)->device().isValid());
524 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
526 // create a new entry (non system item)
527 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
529 // check if the new entry was created
530 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
532 // make sure the new place get removed
535 QList
<QVariant
> args
= itemsInsertedSpy
.takeFirst();
536 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
537 QCOMPARE(range
.first().index
, 5);
538 QCOMPARE(range
.first().count
, 1);
539 QVERIFY(!m_model
->placesItem(5)->isSystemItem());
540 QCOMPARE(m_model
->count(), 18);
543 // check if the removal signal is correct
544 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
545 m_model
->deleteItem(5);
546 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
547 args
= itemsRemovedSpy
.takeFirst();
548 range
= args
.at(0).value
<KItemRangeList
>();
549 QCOMPARE(range
.first().index
, 5);
550 QCOMPARE(range
.first().count
, 1);
551 QTRY_COMPARE(m_model
->count(), 17);
553 //cancel removal (it was removed above)
554 cancelPlaceRemoval(5);
557 void PlacesItemModelTest::testEditBookmark()
559 QScopedPointer
<PlacesItemModel
> other(new PlacesItemModel());
561 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
)), QString());
563 // make sure that the new item will be removed later
566 QSignalSpy
itemsChangedSply(m_model
, &PlacesItemModel::itemsChanged
);
569 m_model
->item(3)->setText(QStringLiteral("Renamed place"));
572 // check if the correct signal was fired
573 QTRY_COMPARE(itemsChangedSply
.count(), 1);
574 QList
<QVariant
> args
= itemsChangedSply
.takeFirst();
575 KItemRangeList range
= args
.at(0).value
<KItemRangeList
>();
576 QCOMPARE(range
.first().index
, 3);
577 QCOMPARE(range
.first().count
, 1);
578 QSet
<QByteArray
> roles
= args
.at(1).value
<QSet
<QByteArray
> >();
579 QCOMPARE(roles
.size(), 1);
580 QCOMPARE(*roles
.begin(), QByteArrayLiteral("text"));
581 QCOMPARE(m_model
->item(3)->text(), QStringLiteral("Renamed place"));
583 // check if the item was updated in the other model
584 QTRY_COMPARE(other
->item(3)->text(), QStringLiteral("Renamed place"));
587 void PlacesItemModelTest::testEditAfterCreation()
589 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
590 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
592 // create a new place
593 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
594 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
596 PlacesItemModel
*model
= new PlacesItemModel();
597 QTRY_COMPARE(model
->count(), m_model
->count());
599 // make sure that the new item will be removed later
603 PlacesItem
*item
= m_model
->placesItem(3);
604 item
->setText(QStringLiteral("Renamed place"));
607 // check if the second model got the changes
608 QTRY_COMPARE(model
->count(), m_model
->count());
609 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
610 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
611 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
612 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
613 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
616 void PlacesItemModelTest::testEditMetadata()
618 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
619 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
621 // create a new place
622 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
623 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
625 // check if the new entry was created
626 PlacesItemModel
*model
= new PlacesItemModel();
627 QTRY_COMPARE(model
->count(), m_model
->count());
629 // make sure that the new item will be removed later
632 // modify place metadata
633 PlacesItem
*item
= m_model
->placesItem(3);
634 item
->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
637 // check if the place was modified in both models
638 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
639 KAboutData::applicationData().componentName());
640 QTRY_COMPARE(model
->placesItem(3)->text(), m_model
->placesItem(3)->text());
641 QTRY_COMPARE(model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
642 m_model
->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
643 QTRY_COMPARE(model
->placesItem(3)->icon(), m_model
->placesItem(3)->icon());
644 QTRY_COMPARE(model
->placesItem(3)->url(), m_model
->placesItem(3)->url());
647 void PlacesItemModelTest::testRefresh()
649 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
650 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
652 // create a new place
653 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
654 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
656 PlacesItemModel
*model
= new PlacesItemModel();
657 QTRY_COMPARE(model
->count(), m_model
->count());
659 // make sure that the new item will be removed later
662 PlacesItem
*item
= m_model
->placesItem(5);
663 PlacesItem
*sameItem
= model
->placesItem(5);
664 QCOMPARE(item
->text(), sameItem
->text());
667 item
->setText(QStringLiteral("Renamed place"));
669 // item from another model is not affected at the moment
670 QVERIFY(item
->text() != sameItem
->text());
675 // item must be equal
676 QTRY_COMPARE(item
->text(), sameItem
->text());
679 void PlacesItemModelTest::testIcons_data()
681 QTest::addColumn
<QUrl
>("url");
682 QTest::addColumn
<QString
>("expectedIconName");
685 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
688 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
691 QTest::newRow("Baloo - Today") << QUrl("timeline:/today") << QStringLiteral("go-jump-today");
694 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
697 void PlacesItemModelTest::testIcons()
700 QFETCH(QString
, expectedIconName
);
702 PlacesItem
*item
= m_model
->placesItem(indexOf(url
));
703 QCOMPARE(item
->icon(), expectedIconName
);
705 for (int r
= 0; r
< m_model
->count(); r
++) {
706 QVERIFY(!m_model
->placesItem(r
)->icon().isEmpty());
710 void PlacesItemModelTest::testDragAndDrop()
712 QList
<QVariant
> args
;
713 KItemRangeList range
;
714 QStringList urls
= initialUrls();
715 QSignalSpy
itemsInsertedSpy(m_model
, &PlacesItemModel::itemsInserted
);
716 QSignalSpy
itemsRemovedSpy(m_model
, &PlacesItemModel::itemsRemoved
);
718 CHECK_PLACES_URLS(initialUrls());
719 // Move the home directory to the end of the places group
720 QMimeData
*dropData
= createMimeData(QList
<int>() << 0);
721 m_model
->dropMimeDataBefore(m_model
->count() - 1, dropData
);
725 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
726 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
728 // remove item from actual position
729 args
= itemsRemovedSpy
.takeFirst();
730 range
= args
.at(0).value
<KItemRangeList
>();
731 QCOMPARE(range
.size(), 1);
732 QCOMPARE(range
.at(0).count
, 1);
733 QCOMPARE(range
.at(0).index
, 0);
735 // insert intem in his group
736 args
= itemsInsertedSpy
.takeFirst();
737 range
= args
.at(0).value
<KItemRangeList
>();
738 QCOMPARE(range
.size(), 1);
739 QCOMPARE(range
.at(0).count
, 1);
740 QCOMPARE(range
.at(0).index
, 4);
742 CHECK_PLACES_URLS(urls
);
744 itemsInsertedSpy
.clear();
745 itemsRemovedSpy
.clear();
747 // Move home directory item back to its original position
748 dropData
= createMimeData(QList
<int>() << 4);
749 m_model
->dropMimeDataBefore(0, dropData
);
753 QTRY_COMPARE(itemsInsertedSpy
.count(), 1);
754 QTRY_COMPARE(itemsRemovedSpy
.count(), 1);
756 // remove item from actual position
757 args
= itemsRemovedSpy
.takeFirst();
758 range
= args
.at(0).value
<KItemRangeList
>();
759 QCOMPARE(range
.size(), 1);
760 QCOMPARE(range
.at(0).count
, 1);
761 QCOMPARE(range
.at(0).index
, 4);
763 // insert intem in the requested position
764 args
= itemsInsertedSpy
.takeFirst();
765 range
= args
.at(0).value
<KItemRangeList
>();
766 QCOMPARE(range
.size(), 1);
767 QCOMPARE(range
.at(0).count
, 1);
768 QCOMPARE(range
.at(0).index
, 0);
770 CHECK_PLACES_URLS(urls
);
773 void PlacesItemModelTest::testHideDevices()
775 QSignalSpy
itemsRemoved(m_model
, &PlacesItemModel::itemsRemoved
);
776 QStringList urls
= initialUrls();
778 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, true);
779 QTRY_VERIFY(m_model
->isGroupHidden(KFilePlacesModel::RemovableDevicesType
));
780 QTRY_COMPARE(itemsRemoved
.count(), 3);
782 // remove removable-devices
783 urls
.removeOne(QStringLiteral("/media/floppy0"));
784 urls
.removeOne(QStringLiteral("/media/XO-Y4"));
785 urls
.removeOne(QStringLiteral("/media/cdrom"));
787 // check if the correct urls was removed
788 CHECK_PLACES_URLS(urls
);
791 m_model
= new PlacesItemModel();
792 QTRY_COMPARE(m_model
->count(), urls
.count());
793 CHECK_PLACES_URLS(urls
);
796 m_model
->setGroupHidden(KFilePlacesModel::RemovableDevicesType
, false);
797 urls
= initialUrls();
798 QTRY_COMPARE(m_model
->count(), urls
.count());
799 CHECK_PLACES_URLS(urls
);
802 void PlacesItemModelTest::testDuplicatedEntries()
804 QStringList urls
= initialUrls();
805 // create a duplicated entry on bookmark
806 KBookmarkManager
*bookmarkManager
= KBookmarkManager::managerForFile(bookmarksFile(), QStringLiteral("kfilePlaces"));
807 KBookmarkGroup root
= bookmarkManager
->root();
808 KBookmark bookmark
= root
.addBookmark(QStringLiteral("Duplicated Search Videos"), QUrl("search:/videos"), {});
810 const QString id
= QUuid::createUuid().toString();
811 bookmark
.setMetaDataItem(QStringLiteral("ID"), id
);
812 bookmark
.setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
813 bookmarkManager
->emitChanged(bookmarkManager
->root());
815 PlacesItemModel
*newModel
= new PlacesItemModel();
816 QTRY_COMPARE(placesUrls(newModel
).count(QStringLiteral("search:/videos")), 1);
817 QTRY_COMPARE(urls
, placesUrls(newModel
));
821 void PlacesItemModelTest::renameAfterCreation()
823 const QUrl tempUrl
= QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation
));
824 QStringList urls
= initialUrls();
825 PlacesItemModel
*model
= new PlacesItemModel();
827 CHECK_PLACES_URLS(urls
);
828 QTRY_COMPARE(model
->count(), m_model
->count());
830 // create a new place
831 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl
, QString());
832 urls
.insert(5, tempUrl
.toLocalFile());
834 // make sure that the new item will be removed later
837 CHECK_PLACES_URLS(urls
);
838 QCOMPARE(model
->count(), m_model
->count());
842 QSignalSpy
changedSpy(m_model
, &PlacesItemModel::itemsChanged
);
844 PlacesItem
*item
= m_model
->placesItem(3);
845 item
->setText(QStringLiteral("New Temporary Dir"));
846 item
->setUrl(item
->url());
847 item
->setIcon(item
->icon());
850 QTRY_COMPARE(changedSpy
.count(), 1);
852 // check if the place was modified in both models
853 QTRY_COMPARE(m_model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
854 QTRY_COMPARE(model
->placesItem(3)->text(), QStringLiteral("New Temporary Dir"));
857 QTEST_MAIN(PlacesItemModelTest
)
859 #include "placesitemmodeltest.moc"