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