@@ -23,8 +23,12 @@
24#include "launcheritem.h"
24#include "launcheritem.h"
25#include "launchermodel.h"
25#include "launchermodel.h"
26+#include "dbusinterface.h"
27#include <QtTest>
28#include <QtTest>
29+#include <QDBusInterface>
31+#include <QDomDocument>
29// This is a mock, specifically to test the LauncherModel
33// This is a mock, specifically to test the LauncherModel
30class MockApp: public unity::shell::application::ApplicationInfoInterface
34class MockApp: public unity::shell::application::ApplicationInfoInterface
@@ -111,186 +115,262 @@ private:
112private Q_SLOTS:
116private Q_SLOTS:
114−// void initTestCase() {
118+ void initTestCase() {
115−// launcherModel = new LauncherModel(this);
119+ launcherModel = new LauncherModel(this);
116−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 0);
120+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 0);
118−// appManager = new MockAppManager(this);
122+ appManager = new MockAppManager(this);
119−// launcherModel->setApplicationManager(appManager);
123+ launcherModel->setApplicationManager(appManager);
122−// // Adding 2 apps to the mock appmanager. Both should appear in the launcher.
126+ // Adding 2 apps to the mock appmanager. Both should appear in the launcher.
123−// void init() {
127+ void init() {
124−// appManager->addApplication(new MockApp("abs-icon"));
128+ appManager->addApplication(new MockApp("abs-icon"));
125−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
129+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
127−// appManager->addApplication(new MockApp("no-icon"));
131+ appManager->addApplication(new MockApp("no-icon"));
128−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
132+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
131−// // Removing apps from appmanager and launcher as pinned ones would stick
135+ // Removing apps from appmanager and launcher as pinned ones would stick
132−// void cleanup() {
136+ void cleanup() {
133−// while (appManager->count() > 0) {
137+ while (appManager->count() > 0) {
134−// appManager->removeApplication(0);
138+ appManager->removeApplication(0);
136−// while (launcherModel->rowCount(QModelIndex()) > 0) {
140+ while (launcherModel->rowCount(QModelIndex()) > 0) {
137−// launcherModel->requestRemove(launcherModel->get(0)->appId());
141+ launcherModel->requestRemove(launcherModel->get(0)->appId());
141−// void testMove() {
145+ void testMove() {
142−// QCOMPARE(launcherModel->get(0)->pinned(), false);
146+ QCOMPARE(launcherModel->get(0)->pinned(), false);
143−// QCOMPARE(launcherModel->get(1)->pinned(), false);
147+ QCOMPARE(launcherModel->get(1)->pinned(), false);
145−// LauncherItemInterface *item0BeforeMove = launcherModel->get(0);
149+ LauncherItemInterface *item0BeforeMove = launcherModel->get(0);
146−// LauncherItemInterface *item1BeforeMove = launcherModel->get(1);
150+ LauncherItemInterface *item1BeforeMove = launcherModel->get(1);
147−// launcherModel->move(1, 0);
151+ launcherModel->move(1, 0);
149−// QCOMPARE(item0BeforeMove, launcherModel->get(1));
153+ QCOMPARE(item0BeforeMove, launcherModel->get(1));
150−// QCOMPARE(item1BeforeMove, launcherModel->get(0));
154+ QCOMPARE(item1BeforeMove, launcherModel->get(0));
152−// // moved item must be pinned now
156+ // moved item must be pinned now
153−// QCOMPARE(item0BeforeMove->pinned(), false);
157+ QCOMPARE(item0BeforeMove->pinned(), false);
154−// QCOMPARE(item1BeforeMove->pinned(), true);
158+ QCOMPARE(item1BeforeMove->pinned(), true);
157−// void testPinning() {
161+ void testPinning() {
158−// QSignalSpy spy(launcherModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
162+ QSignalSpy spy(launcherModel, SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)));
159−// QCOMPARE(launcherModel->get(0)->pinned(), false);
163+ QCOMPARE(launcherModel->get(0)->pinned(), false);
160−// QCOMPARE(launcherModel->get(1)->pinned(), false);
164+ QCOMPARE(launcherModel->get(1)->pinned(), false);
161−// launcherModel->pin(launcherModel->get(0)->appId());
165+ launcherModel->pin(launcherModel->get(0)->appId());
162−// QCOMPARE(launcherModel->get(0)->pinned(), true);
166+ QCOMPARE(launcherModel->get(0)->pinned(), true);
163−// QCOMPARE(launcherModel->get(1)->pinned(), false);
167+ QCOMPARE(launcherModel->get(1)->pinned(), false);
164−// QCOMPARE(spy.count(), 1);
168+ QCOMPARE(spy.count(), 1);
165−// QCOMPARE(spy.at(0).at(2).value<QVector<int>>().first(), (int)LauncherModelInterface::RolePinned);
169+ QCOMPARE(spy.at(0).at(2).value<QVector<int>>().first(), (int)LauncherModelInterface::RolePinned);
167−// launcherModel->requestRemove(launcherModel->get(0)->appId());
171+ launcherModel->requestRemove(launcherModel->get(0)->appId());
168−// QCOMPARE(launcherModel->get(0)->pinned(), false);
172+ QCOMPARE(launcherModel->get(0)->pinned(), false);
169−// QCOMPARE(launcherModel->get(1)->pinned(), false);
173+ QCOMPARE(launcherModel->get(1)->pinned(), false);
170−// QCOMPARE(spy.count(), 2);
174+ QCOMPARE(spy.count(), 2);
171−// QCOMPARE(spy.at(1).at(2).value<QVector<int>>().first(), (int)LauncherModelInterface::RolePinned);
175+ QCOMPARE(spy.at(1).at(2).value<QVector<int>>().first(), (int)LauncherModelInterface::RolePinned);
174−// void testRemove_data() {
178+ void testRemove_data() {
176−// QTest::addColumn<bool>("pinned");
180+ QTest::addColumn<bool>("pinned");
177−// QTest::addColumn<bool>("running");
181+ QTest::addColumn<bool>("running");
179−// QTest::newRow("non-pinned, running") << false << true;
183+ QTest::newRow("non-pinned, running") << false << true;
180−// QTest::newRow("pinned, running") << true << false;
184+ QTest::newRow("pinned, running") << true << false;
181−// QTest::newRow("pinned, non-running") << true << false;
185+ QTest::newRow("pinned, non-running") << true << false;
184−// void testRemove() {
188+ void testRemove() {
185−// QFETCH(bool, pinned);
189+ QFETCH(bool, pinned);
186−// QFETCH(bool, running);
190+ QFETCH(bool, running);
188−// // In the beginning we always have two items
192+ // In the beginning we always have two items
189−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
193+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
191−// // pin one if required
195+ // pin one if required
192−// if (pinned) {
196+ if (pinned) {
193−// launcherModel->pin(launcherModel->get(1)->appId());
197+ launcherModel->pin(launcherModel->get(1)->appId());
196−// // stop it if required
200+ // stop it if required
197−// if (!running) {
201+ if (!running) {
198−// appManager->removeApplication(1);
202+ appManager->removeApplication(1);
201−// // Now remove it
205+ // Now remove it
202−// launcherModel->requestRemove(launcherModel->get(1)->appId());
206+ launcherModel->requestRemove(launcherModel->get(1)->appId());
204−// if (running) {
208+ if (running) {
205−// // both apps are running, both apps must still be here
209+ // both apps are running, both apps must still be here
206−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
210+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
208−// // Item must be unpinned now
212+ // Item must be unpinned now
209−// QCOMPARE(launcherModel->get(1)->pinned(), false);
213+ QCOMPARE(launcherModel->get(1)->pinned(), false);
211−// } else if (pinned) {
215+ } else if (pinned) {
212−// // Item 1 must go away, item 0 is here to stay
216+ // Item 1 must go away, item 0 is here to stay
213−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
217+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
216−// // done our checks. now stop the app if was still running
220+ // done our checks. now stop the app if was still running
217−// if (running) {
221+ if (running) {
218−// appManager->removeApplication(1);
222+ appManager->removeApplication(1);
221−// // It needs to go away in any case now
225+ // It needs to go away in any case now
222−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
226+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
225−// void testQuickListPinningRemoving() {
229+ void testQuickListPinningRemoving() {
226−// // we start with 2 unpinned items
230+ // we start with 2 unpinned items
227−// QCOMPARE(launcherModel->get(0)->pinned(), false);
231+ QCOMPARE(launcherModel->get(0)->pinned(), false);
228−// QCOMPARE(launcherModel->get(1)->pinned(), false);
232+ QCOMPARE(launcherModel->get(1)->pinned(), false);
229−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
233+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
231−// // find the Pin item in the quicklist
235+ // find the Pin item in the quicklist
232−// QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
236+ QuickListModel *model = qobject_cast<QuickListModel*>(launcherModel->get(0)->quickList());
233−// int pinActionIndex = -1;
237+ int pinActionIndex = -1;
234−// for (int i = 0; i < model->rowCount(QModelIndex()); ++i) {
238+ for (int i = 0; i < model->rowCount(QModelIndex()); ++i) {
235−// if (model->get(i).actionId() == "pin_item") {
239+ if (model->get(i).actionId() == "pin_item") {
236−// pinActionIndex = i;
240+ pinActionIndex = i;
240−// QVERIFY(pinActionIndex >= 0);
244+ QVERIFY(pinActionIndex >= 0);
242−// // trigger pin item quicklist action => Item must be pinned now.
246+ // trigger pin item quicklist action => Item must be pinned now.
243−// launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
247+ launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
244−// QCOMPARE(launcherModel->get(0)->pinned(), true);
248+ QCOMPARE(launcherModel->get(0)->pinned(), true);
245−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
249+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
247−// // quicklist needs to transform to remove item. trigger it and check it item goes away
251+ // quicklist needs to transform to remove item. trigger it and check it item goes away
248−// launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
252+ launcherModel->quickListActionInvoked(launcherModel->get(0)->appId(), pinActionIndex);
249−// QCOMPARE(launcherModel->get(0)->pinned(), false);
253+ QCOMPARE(launcherModel->get(0)->pinned(), false);
251−// // still needs to be here as the app is still here
255+ // still needs to be here as the app is still here
252−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
256+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
253−// // close the app
257+ // close the app
254−// appManager->removeApplication(0);
258+ appManager->removeApplication(0);
255−// // Now it needs to go away
259+ // Now it needs to go away
256−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
260+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
259−// void testApplicationFocused() {
263+ void testApplicationFocused() {
260−// // all apps unfocused at beginning...
264+ // all apps unfocused at beginning...
261−// QCOMPARE(launcherModel->get(0)->focused(), false);
265+ QCOMPARE(launcherModel->get(0)->focused(), false);
262−// QCOMPARE(launcherModel->get(1)->focused(), false);
266+ QCOMPARE(launcherModel->get(1)->focused(), false);
264−// appManager->focusApplication("abs-icon");
268+ appManager->focusApplication("abs-icon");
265−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
269+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
266−// QCOMPARE(launcherModel->get(0)->focused(), true);
270+ QCOMPARE(launcherModel->get(0)->focused(), true);
267−// QCOMPARE(launcherModel->get(1)->focused(), false);
271+ QCOMPARE(launcherModel->get(1)->focused(), false);
269−// appManager->focusApplication("no-icon");
273+ appManager->focusApplication("no-icon");
270−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
274+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 2);
271−// QCOMPARE(launcherModel->get(0)->focused(), false);
275+ QCOMPARE(launcherModel->get(0)->focused(), false);
272−// QCOMPARE(launcherModel->get(1)->focused(), true);
276+ QCOMPARE(launcherModel->get(1)->focused(), true);
275−// void testClosingApps() {
279+ void testClosingApps() {
276−// // At the start there are 2 items. Let's pin one.
280+ // At the start there are 2 items. Let's pin one.
277−// launcherModel->pin("abs-icon");
281+ launcherModel->pin("abs-icon");
278−// while (appManager->count() > 0) {
282+ while (appManager->count() > 0) {
279−// appManager->removeApplication(0);
283+ appManager->removeApplication(0);
281−// // The pinned one needs to stay, the other needs to disappear
285+ // The pinned one needs to stay, the other needs to disappear
282−// QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
286+ QCOMPARE(launcherModel->rowCount(QModelIndex()), 1);
283−// QCOMPARE(launcherModel->get(0)->appId(), QLatin1String("abs-icon"));
287+ QCOMPARE(launcherModel->get(0)->appId(), QLatin1String("abs-icon"));
286−// void testGetUrlForAppId() {
290+ void testGetUrlForAppId() {
287−// QCOMPARE(launcherModel->getUrlForAppId(QString()), QString());
291+ QCOMPARE(launcherModel->getUrlForAppId(QString()), QString());
288−// QCOMPARE(launcherModel->getUrlForAppId(""), QString());
292+ QCOMPARE(launcherModel->getUrlForAppId(""), QString());
289−// QCOMPARE(launcherModel->getUrlForAppId("no-name"), QString("application:///no-name.desktop"));
293+ QCOMPARE(launcherModel->getUrlForAppId("no-name"), QString("application:///no-name.desktop"));
290−// QCOMPARE(launcherModel->getUrlForAppId("com.test.good"), QString("appid://com.test.good/first-listed-app/current-user-version"));
294+ QCOMPARE(launcherModel->getUrlForAppId("com.test.good"), QString("application:///com.test.good.desktop"));
291−// QCOMPARE(launcherModel->getUrlForAppId("com.test.good_application"), QString("appid://com.test.good/application/current-user-version"));
295+ QCOMPARE(launcherModel->getUrlForAppId("com.test.good_application"), QString("appid://com.test.good/application/current-user-version"));
292−// QCOMPARE(launcherModel->getUrlForAppId("com.test.good_application_1.2.3"), QString("appid://com.test.good/application/current-user-version"));
296+ QCOMPARE(launcherModel->getUrlForAppId("com.test.good_application_1.2.3"), QString("appid://com.test.good/application/current-user-version"));
299+ void testIntrospection() {
300+ QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher", "org.freedesktop.DBus.Introspectable");
301+ QDBusReply<QString> reply = interface.call("Introspect");
302+ QStringList nodes = extractNodes(reply.value());
303+ QCOMPARE(nodes.count(), launcherModel->rowCount());
305+ appManager->addApplication(new MockApp("foobar"));
306+ reply = interface.call("Introspect");
307+ nodes = extractNodes(reply.value());
308+ QCOMPARE(nodes.contains("foobar"), true);
310+ appManager->removeApplication(2);
311+ reply = interface.call("Introspect");
312+ nodes = extractNodes(reply.value());
313+ QCOMPARE(nodes.contains("foobar"), false);
316+ QStringList extractNodes(const QString &introspectionXml) {
317+ QXmlStreamReader introspectReply(introspectionXml);
320+ while (!introspectReply.atEnd() && !introspectReply.hasError()) {
321+ QXmlStreamReader::TokenType token = introspectReply.readNext();
323+ if (token == QXmlStreamReader::StartElement) {
324+ if (introspectReply.name() == "node" && introspectReply.attributes().count() > 0) {
325+ ret << introspectReply.attributes().value("name").toString();
332+ void testCountEmblems() {
333+ // Call GetAll on abs-icon
334+ QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher/abs_2Dicon", "org.freedesktop.DBus.Properties");
335+ QDBusReply<QVariantMap> reply = interface.call("GetAll");
336+ QVariantMap map = reply.value();
338+ // Make sure GetAll returns a map with count and countVisible props
339+ QCOMPARE(map.contains("count"), true);
340+ QCOMPARE(map.contains("countVisible"), true);
342+ // Make sure count is intitilized to 0 and non-visible
343+ QCOMPARE(map.value("count").toInt(), 0);
344+ QCOMPARE(map.value("countVisible").toBool(), false);
346+ // Now make it visible and set it to 55 through D-Bus
347+ interface.call("Set", "com.canonical.Unity.Launcher.Item", "count", 55);
348+ interface.call("Set", "com.canonical.Unity.Launcher.Item", "countVisible", true);
350+ // Fetch it again using GetAll
351+ reply = interface.call("GetAll");
352+ map = reply.value();
354+ // Make sure values have changed on the D-Bus interface
355+ QCOMPARE(map.value("count").toInt(), 55);
356+ QCOMPARE(map.value("countVisible").toBool(), true);
358+ // Now the item on the upper side of the API
359+ int index = launcherModel->findApplication("abs-icon");
360+ QCOMPARE(index >= 0, true);
362+ // And make sure values have changed there as well
363+ QCOMPARE(launcherModel->get(index)->countVisible(), true);
364+ QCOMPARE(launcherModel->get(index)->count(), 55);
367+ void testRefresh() {
368+ QDBusInterface interface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher", "com.canonical.Unity.Launcher");
369+ QDBusReply<void> reply = interface.call("Refresh");
371+ // Make sure the call to Refresh returned without error.
372+ QCOMPARE(reply.isValid(), true);
296QTEST_GUILESS_MAIN(LauncherModelTest)
376QTEST_GUILESS_MAIN(LauncherModelTest)