]> cloud.milkyroute.net Git - dolphin.git/blob - src/tests/placesitemmodeltest.cpp
Merge remote-tracking branch 'origin/Applications/17.12'
[dolphin.git] / src / tests / placesitemmodeltest.cpp
1 /***************************************************************************
2 * Copyright (C) 2017 by Renato Araujo Oliveira <renato.araujo@kdab.com> *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19
20 #include <QTest>
21 #include <QSignalSpy>
22 #include <QDebug>
23 #include <QList>
24 #include <QByteArray>
25 #include <QStandardPaths>
26 #include <QAction>
27 #include <QDBusInterface>
28 #include <QUrlQuery>
29
30 #include <KBookmarkManager>
31 #include <KConfig>
32 #include <KConfigGroup>
33 #include <KAboutData>
34 #include <KFilePlacesModel>
35
36 #include "panels/places/placesitemmodel.h"
37 #include "panels/places/placesitem.h"
38 #include "views/viewproperties.h"
39 #include "kitemviews/kitemrange.h"
40
41 Q_DECLARE_METATYPE(KItemRangeList)
42 Q_DECLARE_METATYPE(KItemRange)
43
44 #ifdef Q_OS_WIN
45 //c:\ as root for windows
46 #define KDE_ROOT_PATH "C:\\"
47 #else
48 #define KDE_ROOT_PATH "/"
49 #endif
50
51 static QString bookmarksFile()
52 {
53 return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/user-places.xbel";
54 }
55
56 class PlacesItemModelTest : public QObject
57 {
58 Q_OBJECT
59
60 private slots:
61 void init();
62 void cleanup();
63
64 void initTestCase();
65 void cleanupTestCase();
66
67 void testModelSort();
68 void testGroups();
69 void testDeletePlace();
70 void testPlaceItem_data();
71 void testPlaceItem();
72 void testTearDownDevice();
73 void testDefaultViewProperties_data();
74 void testDefaultViewProperties();
75 void testClear();
76 void testHideItem();
77 void testSystemItems();
78 void testEditBookmark();
79 void testEditAfterCreation();
80 void testEditMetadata();
81 void testRefresh();
82 void testIcons_data();
83 void testIcons();
84 void testDragAndDrop();
85 void testHideDevices();
86
87 private:
88 PlacesItemModel* m_model;
89 QSet<int> m_tobeRemoved;
90 QMap<QString, QDBusInterface *> m_interfacesMap;
91
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;
103 };
104
105 #define CHECK_PLACES_URLS(urls) \
106 { \
107 QStringList places = placesUrls(); \
108 if (places != urls) { \
109 qWarning() << "Expected:" << urls; \
110 qWarning() << "Got:" << places; \
111 QCOMPARE(places, urls); \
112 } \
113 }
114
115 void PlacesItemModelTest::setBalooEnabled(bool enabled)
116 {
117 KConfig config(QStringLiteral("baloofilerc"));
118 KConfigGroup basicSettings = config.group("Basic Settings");
119 basicSettings.writeEntry("Indexing-Enabled", enabled);
120 config.sync();
121 }
122
123 int PlacesItemModelTest::indexOf(const QUrl &url)
124 {
125 for (int r = 0; r < m_model->count(); r++) {
126 if (m_model->placesItem(r)->url() == url) {
127 return r;
128 }
129 }
130 return -1;
131 }
132
133 QDBusInterface *PlacesItemModelTest::fakeManager()
134 {
135 return fakeDevice(QStringLiteral("/org/kde/solid/fakehw"));
136 }
137
138 QDBusInterface *PlacesItemModelTest::fakeDevice(const QString &udi)
139 {
140 if (m_interfacesMap.contains(udi)) {
141 return m_interfacesMap[udi];
142 }
143
144 QDBusInterface *iface = new QDBusInterface(QDBusConnection::sessionBus().baseService(), udi);
145 m_interfacesMap[udi] = iface;
146
147 return iface;
148 }
149
150 QStringList PlacesItemModelTest::placesUrls(PlacesItemModel *model) const
151 {
152 QStringList urls;
153 if (!model) {
154 model = m_model;
155 }
156
157 for (int row = 0; row < model->count(); ++row) {
158 urls << model->placesItem(row)->url().toDisplayString(QUrl::PreferLocalFile);
159 }
160 return urls;
161 }
162
163 QStringList PlacesItemModelTest::initialUrls() const
164 {
165 static QStringList urls;
166 if (urls.isEmpty()) {
167 urls << QDir::homePath() << QStringLiteral(KDE_ROOT_PATH) << QStringLiteral("trash:/")
168 << QStringLiteral("remote:/")
169 << QStringLiteral("timeline:/today") << QStringLiteral("timeline:/yesterday") << QStringLiteral("timeline:/thismonth") << QStringLiteral("timeline:/lastmonth")
170 << QStringLiteral("search:/documents") << QStringLiteral("search:/images") << QStringLiteral("search:/audio") << QStringLiteral("search:/videos")
171 << QStringLiteral("/media/nfs") << QStringLiteral("/foreign")
172 << QStringLiteral("/media/floppy0") << QStringLiteral("/media/XO-Y4") << QStringLiteral("/media/cdrom");
173 }
174 return urls;
175 }
176
177 void PlacesItemModelTest::createPlaceItem(const QString &text, const QUrl &url, const QString &icon)
178 {
179 m_model->createPlacesItem(text, url, icon);
180 }
181
182 void PlacesItemModelTest::removePlaceAfter(int index)
183 {
184 m_tobeRemoved.insert(index);
185 }
186
187 void PlacesItemModelTest::cancelPlaceRemoval(int index)
188 {
189 m_tobeRemoved.remove(index);
190 }
191
192 void PlacesItemModelTest::removeTestUserData()
193 {
194 // user hardcoded path to avoid removal of any user personal data
195 QDir dir(QStringLiteral("/home/renato/.qttest/share/placesitemmodeltest"));
196 if (dir.exists()) {
197 QVERIFY(dir.removeRecursively());
198 }
199 }
200
201 QMimeData *PlacesItemModelTest::createMimeData(const QList<int> &indexes) const
202 {
203 QByteArray itemData;
204 QDataStream stream(&itemData, QIODevice::WriteOnly);
205 QList<QUrl> urls;
206
207 for (int index : indexes) {
208 const QUrl itemUrl = m_model->placesItem(index)->url();
209 if (itemUrl.isValid()) {
210 urls << itemUrl;
211 }
212 stream << index;
213 }
214
215 QMimeData* mimeData = new QMimeData();
216 mimeData->setUrls(urls);
217 // copied from PlacesItemModel::internalMimeType()
218 const QString internalMimeType = "application/x-dolphinplacesmodel-" +
219 QString::number((qptrdiff)m_model);
220 mimeData->setData(internalMimeType, itemData);
221 return mimeData;
222 }
223
224 void PlacesItemModelTest::init()
225 {
226 m_model = new PlacesItemModel();
227 // WORKAROUND: need to wait for bookmark to load, check: PlacesItemModel::updateBookmarks
228 QTest::qWait(300);
229 QCOMPARE(m_model->count(), 17);
230 }
231
232 void PlacesItemModelTest::cleanup()
233 {
234 for (int i : m_tobeRemoved) {
235 int before = m_model->count();
236 m_model->deleteItem(i);
237 QTRY_COMPARE(m_model->count(), before - 1);
238 }
239 m_tobeRemoved.clear();
240 delete m_model;
241 m_model = nullptr;
242 removeTestUserData();
243 }
244
245 void PlacesItemModelTest::initTestCase()
246 {
247 QStandardPaths::setTestModeEnabled(true);
248 // remove test user data
249 removeTestUserData();
250
251 const QString fakeHw = QFINDTESTDATA("data/fakecomputer.xml");
252 QVERIFY(!fakeHw.isEmpty());
253 qputenv("SOLID_FAKEHW", QFile::encodeName(fakeHw));
254
255 setBalooEnabled(true);
256 const QString bookmarsFileName = bookmarksFile();
257 if (QFileInfo::exists(bookmarsFileName)) {
258 // Ensure we'll have a clean bookmark file to start
259 QVERIFY(QFile::remove(bookmarsFileName));
260 }
261
262 qRegisterMetaType<KItemRangeList>();
263 qRegisterMetaType<KItemRange>();
264 }
265
266 void PlacesItemModelTest::cleanupTestCase()
267 {
268 qDeleteAll(m_interfacesMap);
269 QFile::remove(bookmarksFile());
270
271 // Remove any previous properties file
272 removeTestUserData();
273 }
274
275 void PlacesItemModelTest::testModelSort()
276 {
277 CHECK_PLACES_URLS(initialUrls());
278 }
279
280 void PlacesItemModelTest::testGroups()
281 {
282 const auto groups = m_model->groups();
283
284 QCOMPARE(groups.size(), 6);
285
286 QCOMPARE(groups.at(0).first, 0);
287 QCOMPARE(groups.at(0).second.toString(), QStringLiteral("Places"));
288
289 QCOMPARE(groups.at(1).first, 3);
290 QCOMPARE(groups.at(1).second.toString(), QStringLiteral("Remote"));
291
292 QCOMPARE(groups.at(2).first, 4);
293 QCOMPARE(groups.at(2).second.toString(), QStringLiteral("Recently Saved"));
294
295 QCOMPARE(groups.at(3).first, 8);
296 QCOMPARE(groups.at(3).second.toString(), QStringLiteral("Search For"));
297
298 QCOMPARE(groups.at(4).first, 12);
299 QCOMPARE(groups.at(4).second.toString(), QStringLiteral("Devices"));
300
301 QCOMPARE(groups.at(5).first, 14);
302 QCOMPARE(groups.at(5).second.toString(), QStringLiteral("Removable Devices"));
303 }
304
305 void PlacesItemModelTest::testPlaceItem_data()
306 {
307 QTest::addColumn<QUrl>("url");
308 QTest::addColumn<bool>("expectedIsHidden");
309 QTest::addColumn<bool>("expectedIsSystemItem");
310 QTest::addColumn<QString>("expectedGroup");
311 QTest::addColumn<bool>("expectedStorageSetupNeeded");
312
313 // places
314 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << false << true << QStringLiteral("Places") << false;
315
316 // baloo -search
317 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << false << true << QStringLiteral("Search For") << false;
318
319 // baloo - timeline
320 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << false << true << QStringLiteral("Recently Saved") << false;
321
322 // devices
323 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << false << false << QStringLiteral("Removable Devices") << false;
324 }
325
326 void PlacesItemModelTest::testPlaceItem()
327 {
328 QFETCH(QUrl, url);
329 QFETCH(bool, expectedIsHidden);
330 QFETCH(bool, expectedIsSystemItem);
331 QFETCH(QString, expectedGroup);
332 QFETCH(bool, expectedStorageSetupNeeded);
333
334 const int index = indexOf(url);
335 PlacesItem *item = m_model->placesItem(index);
336 QCOMPARE(item->url(), url);
337 QCOMPARE(item->isHidden(), expectedIsHidden);
338 QCOMPARE(item->isSystemItem(), expectedIsSystemItem);
339 QCOMPARE(item->group(), expectedGroup);
340 QCOMPARE(item->storageSetupNeeded(), expectedStorageSetupNeeded);
341 }
342
343 void PlacesItemModelTest::testDeletePlace()
344 {
345 const QUrl tempUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
346 QStringList urls = initialUrls();
347 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
348 QSignalSpy itemsRemovedSpy(m_model, &PlacesItemModel::itemsRemoved);
349
350 PlacesItemModel *model = new PlacesItemModel();
351
352 // create a new place
353 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl, QString());
354 urls.insert(3, tempUrl.toLocalFile());
355
356 // check if the new entry was created
357 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
358 CHECK_PLACES_URLS(urls);
359 QTRY_COMPARE(model->count(), m_model->count());
360
361 // delete item
362 m_model->deleteItem(3);
363
364 // make sure that the new item is removed
365 QTRY_COMPARE(itemsRemovedSpy.count(), 1);
366 QTRY_COMPARE(m_model->count(), 17);
367 CHECK_PLACES_URLS(initialUrls());
368 QTRY_COMPARE(model->count(), m_model->count());
369 }
370
371 void PlacesItemModelTest::testTearDownDevice()
372 {
373 const QUrl mediaUrl = QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
374 int index = indexOf(mediaUrl);
375 QVERIFY(index != -1);
376
377 auto ejectAction = m_model->ejectAction(index);
378 QVERIFY(!ejectAction);
379
380 auto teardownAction = m_model->teardownAction(index);
381 QVERIFY(teardownAction);
382
383 QCOMPARE(m_model->count(), 17);
384
385 QSignalSpy spyItemsRemoved(m_model, &PlacesItemModel::itemsRemoved);
386 fakeManager()->call(QStringLiteral("unplug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
387 QTRY_COMPARE(m_model->count(), 16);
388 QCOMPARE(spyItemsRemoved.count(), 1);
389 const QList<QVariant> spyItemsRemovedArgs = spyItemsRemoved.takeFirst();
390 const KItemRangeList removedRange = spyItemsRemovedArgs.at(0).value<KItemRangeList>();
391 QCOMPARE(removedRange.size(), 1);
392 QCOMPARE(removedRange.first().index, index);
393 QCOMPARE(removedRange.first().count, 1);
394
395 QCOMPARE(indexOf(mediaUrl), -1);
396
397 QSignalSpy spyItemsInserted(m_model, &PlacesItemModel::itemsInserted);
398 fakeManager()->call(QStringLiteral("plug"), "/org/kde/solid/fakehw/volume_part1_size_993284096");
399 QTRY_COMPARE(m_model->count(), 17);
400 QCOMPARE(spyItemsInserted.count(), 1);
401 index = indexOf(mediaUrl);
402
403 const QList<QVariant> args = spyItemsInserted.takeFirst();
404 const KItemRangeList insertedRange = args.at(0).value<KItemRangeList>();
405 QCOMPARE(insertedRange.size(), 1);
406 QCOMPARE(insertedRange.first().index, index);
407 QCOMPARE(insertedRange.first().count, 1);
408 }
409
410 void PlacesItemModelTest::testDefaultViewProperties_data()
411 {
412 QTest::addColumn<QUrl>("url");
413 QTest::addColumn<DolphinView::Mode>("expectedViewMode");
414 QTest::addColumn<bool>("expectedPreviewShow");
415 QTest::addColumn<QList<QByteArray> >("expectedVisibleRole");
416
417 // places
418 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << DolphinView::IconsView << true << QList<QByteArray>({"text"});
419
420 // baloo -search
421 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << DolphinView::DetailsView << false << QList<QByteArray>({"text", "path"});
422
423 // audio files
424 QTest::newRow("Places - Audio") << QUrl("search:/audio") << DolphinView::DetailsView << false << QList<QByteArray>({"text", "artist", "album"});
425
426 // baloo - timeline
427 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << DolphinView::DetailsView << true << QList<QByteArray>({"text", "modificationtime"});
428
429 // devices
430 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << DolphinView::IconsView << true << QList<QByteArray>({"text"});
431
432 }
433
434 void PlacesItemModelTest::testDefaultViewProperties()
435 {
436 QFETCH(QUrl, url);
437 QFETCH(DolphinView::Mode, expectedViewMode);
438 QFETCH(bool, expectedPreviewShow);
439 QFETCH(QList<QByteArray>, expectedVisibleRole);
440
441 ViewProperties properties(KFilePlacesModel::convertedUrl(url));
442 QCOMPARE(properties.viewMode(), expectedViewMode);
443 QCOMPARE(properties.previewsShown(), expectedPreviewShow);
444 QCOMPARE(properties.visibleRoles(), expectedVisibleRole);
445 }
446
447 void PlacesItemModelTest::testClear()
448 {
449 QCOMPARE(m_model->count(), 17);
450 m_model->clear();
451 QCOMPARE(m_model->count(), 0);
452 QCOMPARE(m_model->hiddenCount(), 0);
453 m_model->refresh();
454 QTRY_COMPARE(m_model->count(), 17);
455 }
456
457 void PlacesItemModelTest::testHideItem()
458 {
459 const QUrl mediaUrl = QUrl::fromLocalFile(QStringLiteral("/media/XO-Y4"));
460 const int index = indexOf(mediaUrl);
461
462 PlacesItem *item = m_model->placesItem(index);
463
464 QSignalSpy spyItemsRemoved(m_model, &PlacesItemModel::itemsRemoved);
465 QList<QVariant> spyItemsRemovedArgs;
466 KItemRangeList removedRange;
467
468 QSignalSpy spyItemsInserted(m_model, &PlacesItemModel::itemsInserted);
469 QList<QVariant> spyItemsInsertedArgs;
470 KItemRangeList insertedRange;
471 QVERIFY(item);
472
473 // hide an item
474 item->setHidden(true);
475
476 // check if items removed was fired
477 QTRY_COMPARE(m_model->count(), 16);
478 QCOMPARE(spyItemsRemoved.count(), 1);
479 spyItemsRemovedArgs = spyItemsRemoved.takeFirst();
480 removedRange = spyItemsRemovedArgs.at(0).value<KItemRangeList>();
481 QCOMPARE(removedRange.size(), 1);
482 QCOMPARE(removedRange.first().index, index);
483 QCOMPARE(removedRange.first().count, 1);
484
485 // allow model to show hidden items
486 m_model->setHiddenItemsShown(true);
487
488 // check if the items inserted was fired
489 spyItemsInsertedArgs = spyItemsInserted.takeFirst();
490 insertedRange = spyItemsInsertedArgs.at(0).value<KItemRangeList>();
491 QCOMPARE(insertedRange.size(), 1);
492 QCOMPARE(insertedRange.first().index, index);
493 QCOMPARE(insertedRange.first().count, 1);
494
495 // mark item as visible
496 item = m_model->placesItem(index);
497 item->setHidden(false);
498
499 // mark model to hide invisible items
500 m_model->setHiddenItemsShown(true);
501
502 QTRY_COMPARE(m_model->count(), 17);
503 }
504
505 void PlacesItemModelTest::testSystemItems()
506 {
507 QCOMPARE(m_model->count(), 17);
508 for (int r = 0; r < m_model->count(); r++) {
509 QCOMPARE(m_model->placesItem(r)->isSystemItem(), !m_model->placesItem(r)->device().isValid());
510 }
511
512 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
513
514 // create a new entry (non system item)
515 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation)), QString());
516
517 // check if the new entry was created
518 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
519
520 // make sure the new place get removed
521 removePlaceAfter(3);
522
523 QList<QVariant> args = itemsInsertedSpy.takeFirst();
524 KItemRangeList range = args.at(0).value<KItemRangeList>();
525 QCOMPARE(range.first().index, 3);
526 QCOMPARE(range.first().count, 1);
527 QVERIFY(!m_model->placesItem(3)->isSystemItem());
528 QCOMPARE(m_model->count(), 18);
529
530 QTest::qWait(300);
531 // check if the removal signal is correct
532 QSignalSpy itemsRemovedSpy(m_model, &PlacesItemModel::itemsRemoved);
533 m_model->deleteItem(3);
534 QTRY_COMPARE(itemsRemovedSpy.count(), 1);
535 args = itemsRemovedSpy.takeFirst();
536 range = args.at(0).value<KItemRangeList>();
537 QCOMPARE(range.first().index, 3);
538 QCOMPARE(range.first().count, 1);
539 QTRY_COMPARE(m_model->count(), 17);
540
541 //cancel removal (it was removed above)
542 cancelPlaceRemoval(3);
543 }
544
545 void PlacesItemModelTest::testEditBookmark()
546 {
547 const QUrl tempUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
548 QScopedPointer<PlacesItemModel> other(new PlacesItemModel());
549
550 createPlaceItem(QStringLiteral("Temporary Dir"), QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation)), QString());
551
552 // make sure that the new item will be removed later
553 removePlaceAfter(3);
554
555 QSignalSpy itemsChangedSply(m_model, &PlacesItemModel::itemsChanged);
556
557 // modify place text
558 m_model->item(3)->setText(QStringLiteral("Renamed place"));
559 m_model->refresh();
560
561 // check if the correct signal was fired
562 QTRY_COMPARE(itemsChangedSply.count(), 1);
563 QList<QVariant> args = itemsChangedSply.takeFirst();
564 KItemRangeList range = args.at(0).value<KItemRangeList>();
565 QCOMPARE(range.first().index, 3);
566 QCOMPARE(range.first().count, 1);
567 QSet<QByteArray> roles = args.at(1).value<QSet<QByteArray> >();
568 QCOMPARE(roles.size(), 1);
569 QCOMPARE(*roles.begin(), QByteArrayLiteral("text"));
570 QCOMPARE(m_model->item(3)->text(), QStringLiteral("Renamed place"));
571
572 // check if the item was updated in the other model
573 QTRY_COMPARE(other->item(3)->text(), QStringLiteral("Renamed place"));
574 }
575
576 void PlacesItemModelTest::testEditAfterCreation()
577 {
578 const QUrl tempUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
579 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
580
581 // create a new place
582 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl, QString());
583 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
584
585 PlacesItemModel *model = new PlacesItemModel();
586 QTRY_COMPARE(model->count(), m_model->count());
587
588 // make sure that the new item will be removed later
589 removePlaceAfter(3);
590
591 // modify place text
592 PlacesItem *item = m_model->placesItem(3);
593 item->setText(QStringLiteral("Renamed place"));
594 m_model->refresh();
595
596 // check if the second model got the changes
597 QTRY_COMPARE(model->count(), m_model->count());
598 QTRY_COMPARE(model->placesItem(3)->text(), m_model->placesItem(3)->text());
599 QTRY_COMPARE(model->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
600 m_model->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
601 QTRY_COMPARE(model->placesItem(3)->icon(), m_model->placesItem(3)->icon());
602 QTRY_COMPARE(model->placesItem(3)->url(), m_model->placesItem(3)->url());
603 }
604
605 void PlacesItemModelTest::testEditMetadata()
606 {
607 const QUrl tempUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
608 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
609
610 // create a new place
611 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl, QString());
612 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
613
614 // check if the new entry was created
615 PlacesItemModel *model = new PlacesItemModel();
616 QTRY_COMPARE(model->count(), m_model->count());
617
618 // make sure that the new item will be removed later
619 removePlaceAfter(3);
620
621 // modify place metadata
622 PlacesItem *item = m_model->placesItem(3);
623 item->bookmark().setMetaDataItem(QStringLiteral("OnlyInApp"), KAboutData::applicationData().componentName());
624 m_model->refresh();
625
626 // check if the place was modified in both models
627 QTRY_COMPARE(model->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
628 KAboutData::applicationData().componentName());
629 QTRY_COMPARE(model->placesItem(3)->text(), m_model->placesItem(3)->text());
630 QTRY_COMPARE(model->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")),
631 m_model->placesItem(3)->bookmark().metaDataItem(QStringLiteral("OnlyInApp")));
632 QTRY_COMPARE(model->placesItem(3)->icon(), m_model->placesItem(3)->icon());
633 QTRY_COMPARE(model->placesItem(3)->url(), m_model->placesItem(3)->url());
634 }
635
636 void PlacesItemModelTest::testRefresh()
637 {
638 const QUrl tempUrl = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
639 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
640
641 // create a new place
642 createPlaceItem(QStringLiteral("Temporary Dir"), tempUrl, QString());
643 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
644
645 PlacesItemModel *model = new PlacesItemModel();
646 QTRY_COMPARE(model->count(), m_model->count());
647
648 // make sure that the new item will be removed later
649 removePlaceAfter(3);
650
651 PlacesItem *item = m_model->placesItem(3);
652 PlacesItem *sameItem = model->placesItem(3);
653 QCOMPARE(item->text(), sameItem->text());
654
655 // modify place text
656 item->setText(QStringLiteral("Renamed place"));
657
658 // item from another model is not affected at the moment
659 QVERIFY(item->text() != sameItem->text());
660
661 // propagate change
662 m_model->refresh();
663
664 // item must be equal
665 QTRY_COMPARE(item->text(), sameItem->text());
666 }
667
668 void PlacesItemModelTest::testIcons_data()
669 {
670 QTest::addColumn<QUrl>("url");
671 QTest::addColumn<QString>("expectedIconName");
672
673 // places
674 QTest::newRow("Places - Home") << QUrl::fromLocalFile(QDir::homePath()) << QStringLiteral("user-home");
675
676 // baloo -search
677 QTest::newRow("Baloo - Documents") << QUrl("search:/documents") << QStringLiteral("folder-text");
678
679 // baloo - timeline
680 QTest::newRow("Baloo - Last Month") << QUrl("timeline:/lastmonth") << QStringLiteral("view-calendar-month");
681
682 // devices
683 QTest::newRow("Devices - Floppy") << QUrl("file:///media/floppy0") << QStringLiteral("blockdevice");
684 }
685
686 void PlacesItemModelTest::testIcons()
687 {
688 QFETCH(QUrl, url);
689 QFETCH(QString, expectedIconName);
690
691 PlacesItem *item = m_model->placesItem(indexOf(url));
692 QCOMPARE(item->icon(), expectedIconName);
693
694 for (int r = 0; r < m_model->count(); r++) {
695 QVERIFY(!m_model->placesItem(r)->icon().isEmpty());
696 }
697 }
698
699 void PlacesItemModelTest::testDragAndDrop()
700 {
701 QList<QVariant> args;
702 KItemRangeList range;
703 QStringList urls = initialUrls();
704 QSignalSpy itemsInsertedSpy(m_model, &PlacesItemModel::itemsInserted);
705 QSignalSpy itemsRemovedSpy(m_model, &PlacesItemModel::itemsRemoved);
706
707 CHECK_PLACES_URLS(initialUrls());
708 // 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
709 QMimeData *dropData = createMimeData(QList<int>() << 1);
710 m_model->dropMimeDataBefore(m_model->count() - 1, dropData);
711 urls.move(1, 2);
712 delete dropData;
713
714 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
715 QTRY_COMPARE(itemsRemovedSpy.count(), 1);
716
717 // remove item from actual position
718 args = itemsRemovedSpy.takeFirst();
719 range = args.at(0).value<KItemRangeList>();
720 QCOMPARE(range.size(), 1);
721 QCOMPARE(range.at(0).count, 1);
722 QCOMPARE(range.at(0).index, 1);
723
724 // insert intem in his group
725 args = itemsInsertedSpy.takeFirst();
726 range = args.at(0).value<KItemRangeList>();
727 QCOMPARE(range.size(), 1);
728 QCOMPARE(range.at(0).count, 1);
729 QCOMPARE(range.at(0).index, 2);
730
731 CHECK_PLACES_URLS(urls);
732
733 itemsInsertedSpy.clear();
734 itemsRemovedSpy.clear();
735
736 // Move the KDE_ROOT_PATH to his original position
737 dropData = createMimeData(QList<int>() << 2);
738 m_model->dropMimeDataBefore(1, dropData);
739 urls.move(2, 1);
740 delete dropData;
741
742 QTRY_COMPARE(itemsInsertedSpy.count(), 1);
743 QTRY_COMPARE(itemsRemovedSpy.count(), 1);
744
745 // remove item from actual position
746 args = itemsRemovedSpy.takeFirst();
747 range = args.at(0).value<KItemRangeList>();
748 QCOMPARE(range.size(), 1);
749 QCOMPARE(range.at(0).count, 1);
750 QCOMPARE(range.at(0).index, 2);
751
752 // insert intem in the requested position
753 args = itemsInsertedSpy.takeFirst();
754 range = args.at(0).value<KItemRangeList>();
755 QCOMPARE(range.size(), 1);
756 QCOMPARE(range.at(0).count, 1);
757 QCOMPARE(range.at(0).index, 1);
758
759 CHECK_PLACES_URLS(urls);
760 }
761
762 void PlacesItemModelTest::testHideDevices()
763 {
764 QSignalSpy itemsRemoved(m_model, &PlacesItemModel::itemsRemoved);
765 QStringList urls = initialUrls();
766
767 m_model->setGroupHidden(KFilePlacesModel::RemovableDevicesType, true);
768 QTRY_VERIFY(m_model->isGroupHidden(KFilePlacesModel::RemovableDevicesType));
769 QTRY_COMPARE(itemsRemoved.count(), 3);
770
771 // remove removable-devices
772 urls.removeOne(QStringLiteral("/media/floppy0"));
773 urls.removeOne(QStringLiteral("/media/XO-Y4"));
774 urls.removeOne(QStringLiteral("/media/cdrom"));
775
776 // check if the correct urls was removed
777 CHECK_PLACES_URLS(urls);
778
779 delete m_model;
780 m_model = new PlacesItemModel();
781 QTRY_COMPARE(m_model->count(), urls.count());
782 CHECK_PLACES_URLS(urls);
783 }
784
785 QTEST_MAIN(PlacesItemModelTest)
786
787 #include "placesitemmodeltest.moc"