I have made the following changes intended for : CE:UX:MTF / lipstick Please review and accept or decline. BOSS has already run some checks on this request. See the "Messages from BOSS" section below.
https://build.pub.meego.com//request/show/7118 Thank You, Islam Amer [This message was auto-generated] --- Request # 7118: Messages from BOSS: State: review at 2012-10-23T14:02:00 by bossbot Reviews: accepted by bossbot : Prechecks succeeded. new for CE-maintainers : Please replace this text with a review and approve/reject the review (not the SR). BOSS will take care of the rest Changes: submit: Project:MTF:UX / lipstick -> CE:UX:MTF / lipstick changes files: -------------- --- lipstick.changes +++ lipstick.changes @@ -0,0 +1,4 @@ +* Tue Oct 23 2012 Vesa Halttunen <[email protected]> - 0.4.2 +- Notification manager extension for getting an application's notifications +- Support for remote actions in notifications + old: ---- lipstick-0.4.1.tar.bz2 new: ---- lipstick-0.4.2.tar.bz2 spec files: ----------- --- lipstick.spec +++ lipstick.spec @@ -9,7 +9,7 @@ # << macros Summary: QML toolkit for homescreen creation -Version: 0.4.1 +Version: 0.4.2 Release: 1 Group: System/Libraries License: LGPLv2.1 @@ -22,7 +22,7 @@ BuildRequires: pkgconfig(QtDeclarative) BuildRequires: pkgconfig(QtSensors) BuildRequires: pkgconfig(contentaction-0.1) -BuildRequires: pkgconfig(mlite) +BuildRequires: pkgconfig(mlite) >= 0.0.6 BuildRequires: pkgconfig(xcomposite) BuildRequires: pkgconfig(xdamage) other changes: -------------- ++++++ lipstick-0.4.1.tar.bz2 -> lipstick-0.4.2.tar.bz2 --- .gitignore +++ .gitignore @@ -1,18 +0,0 @@ -Makefile -*.o -*gen_*.h -*gen_*.cpp -*gen_*.o -*moc_*.h -*moc_*.cpp -*moc_*.o -*~ -*.log -*.log.xml -*.gcno -*.gcda -*.pro.user -configure-stamp -build-stamp -.project -.cproject --- plugin/.gitignore +++ plugin/.gitignore @@ -1 +0,0 @@ -liblipstickplugin.so --- src/.gitignore +++ src/.gitignore @@ -1,2 +0,0 @@ -liblipstick.* -pkgconfig --- src/notifications/.gitignore +++ src/notifications/.gitignore @@ -1 +0,0 @@ -notificationmanageradaptor.* --- src/notifications/notification.cpp +++ src/notifications/notification.cpp @@ -13,12 +13,14 @@ ** ****************************************************************************/ +#include <QDBusArgument> #include "notificationmanager.h" #include "notification.h" -Notification::Notification(const QString &appName, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout, QObject *parent) : +Notification::Notification(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout, QObject *parent) : QObject(parent), appName_(appName), + replacesId_(replacesId), appIcon_(appIcon), summary_(summary), body_(body), @@ -28,6 +30,25 @@ { } +Notification::Notification() : + replacesId_(0), + expireTimeout_(-1) +{ +} + +Notification::Notification(const Notification ¬ification) : + QObject(notification.parent()), + appName_(notification.appName_), + replacesId_(notification.replacesId_), + appIcon_(notification.appIcon_), + summary_(notification.summary_), + body_(notification.body_), + actions_(notification.actions_), + hints_(notification.hints_), + expireTimeout_(notification.expireTimeout_) +{ +} + QString Notification::appName() const { return appName_; @@ -38,6 +59,11 @@ appName_ = appName; } +uint Notification::replacesId() const +{ + return replacesId_; +} + QString Notification::appIcon() const { return appIcon_; @@ -129,3 +155,33 @@ { return timestamp().toString("hh:mm:ss"); } + +QDBusArgument &operator<<(QDBusArgument &argument, const Notification ¬ification) +{ + argument.beginStructure(); + argument << notification.appName_; + argument << notification.replacesId_; + argument << notification.appIcon_; + argument << notification.summary_; + argument << notification.body_; + argument << notification.actions_; + argument << notification.hints_; + argument << notification.expireTimeout_; + argument.endStructure(); + return argument; +} + +const QDBusArgument &operator>>(const QDBusArgument &argument, Notification ¬ification) +{ + argument.beginStructure(); + argument >> notification.appName_; + argument >> notification.replacesId_; + argument >> notification.appIcon_; + argument >> notification.summary_; + argument >> notification.body_; + argument >> notification.actions_; + argument >> notification.hints_; + argument >> notification.expireTimeout_; + argument.endStructure(); + return argument; +} --- src/notifications/notification.h +++ src/notifications/notification.h @@ -21,6 +21,8 @@ #include <QDateTime> #include <QVariantHash> +class QDBusArgument; + /*! * An object for storing information about a single notification. */ @@ -28,6 +30,7 @@ { Q_OBJECT Q_PROPERTY(QString appName READ appName) + Q_PROPERTY(uint replacesId READ replacesId) Q_PROPERTY(QString appIcon READ appIcon) Q_PROPERTY(QString summary READ summary NOTIFY summaryChanged) Q_PROPERTY(QString body READ body NOTIFY bodyChanged) @@ -42,6 +45,7 @@ * Creates an object for storing information about a single notification. * * \param appName name of the application sending the notification + * \param replacesID the ID of the notification * \param appIcon icon ID of the application sending the notification * \param summary summary text for the notification * \param body body text for the notification @@ -50,7 +54,7 @@ * \param expireTimeout expiration timeout for the notification * \param parent the parent QObject */ - Notification(const QString &appName, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout, QObject *parent = 0); + Notification(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout, QObject *parent = 0); //! Returns the name of the application sending the notification QString appName() const; @@ -58,6 +62,9 @@ //! Sets the name of the application sending the notification void setAppName(const QString &appName); + //! Returns the ID of the notification + uint replacesId() const; + //! Returns the icon ID of the application sending the notification QString appIcon() const; @@ -103,6 +110,27 @@ //! Returns the timestamp for the notification in localized text format QString localizedTimestamp() const; + //! \internal + /*! + * Creates a new uninitialized representation of a notification. This + * constructor should only be used for populating the notification list + * from D-Bus structures. + */ + Notification(); + + /*! + * Creates a copy of an existing representation of a notification. + * This constructor should only be used for populating the notification + * list from D-Bus structures. + * + * \param notification the notification representation to a create copy of + */ + explicit Notification(const Notification ¬ification); + + friend QDBusArgument &operator<<(QDBusArgument &, const Notification &); + friend const QDBusArgument &operator>>(const QDBusArgument &, Notification &); + //! \internal_end + signals: /*! * Sent when an action defined for the notification is invoked. @@ -127,6 +155,9 @@ //! Name of the application sending the notification QString appName_; + //! The ID of the notification + uint replacesId_; + //! Icon ID of the application sending the notification QString appIcon_; @@ -146,4 +177,7 @@ int expireTimeout_; }; +Q_DECLARE_METATYPE(Notification) +Q_DECLARE_METATYPE(QList<Notification>) + #endif // NOTIFICATION_H --- src/notifications/notificationlistmodel.cpp +++ src/notifications/notificationlistmodel.cpp @@ -48,5 +48,5 @@ bool NotificationListModel::notificationShouldBeShown(Notification *notification) { - return notification->hints().value(NotificationManager::HINT_CLASS).toString() != "system" && !notification->body().isEmpty() && !notification->summary().isEmpty(); + return !notification->body().isEmpty() && !notification->summary().isEmpty(); } --- src/notifications/notificationmanager.cpp +++ src/notifications/notificationmanager.cpp @@ -20,6 +20,7 @@ #include <QSqlQuery> #include <QSqlRecord> #include <QSqlTableModel> +#include <mremoteaction.h> #include <sys/statfs.h> #include "categorydefinitionstore.h" #include "notificationmanageradaptor.h" @@ -52,16 +53,14 @@ const char *NotificationManager::HINT_SUPPRESS_SOUND = "suppress-sound"; const char *NotificationManager::HINT_X = "x"; const char *NotificationManager::HINT_Y = "y"; -const char *NotificationManager::HINT_CLASS = "x-nemo-class"; const char *NotificationManager::HINT_ICON = "x-nemo-icon"; const char *NotificationManager::HINT_ITEM_COUNT = "x-nemo-item-count"; const char *NotificationManager::HINT_TIMESTAMP = "x-nemo-timestamp"; const char *NotificationManager::HINT_PREVIEW_ICON = "x-nemo-preview-icon"; const char *NotificationManager::HINT_PREVIEW_BODY = "x-nemo-preview-body"; const char *NotificationManager::HINT_PREVIEW_SUMMARY = "x-nemo-preview-summary"; +const char *NotificationManager::HINT_REMOTE_ACTION_PREFIX = "x-nemo-remote-action-"; const char *NotificationManager::HINT_USER_REMOVABLE = "x-nemo-user-removable"; -const char *NotificationManager::HINT_GENERIC_TEXT_TRANSLATION_ID = "x-nemo-generic-text-translation-id"; -const char *NotificationManager::HINT_GENERIC_TEXT_TRANSLATION_CATALOGUE = "x-nemo-generic-text-translation-catalogue"; NotificationManager *NotificationManager::instance_ = 0; @@ -81,6 +80,9 @@ committed(true) { qDBusRegisterMetaType<QVariantHash>(); + qDBusRegisterMetaType<Notification>(); + qDBusRegisterMetaType<QList<Notification> >(); + new NotificationManagerAdaptor(this); QDBusConnection::sessionBus().registerService("org.freedesktop.Notifications"); QDBusConnection::sessionBus().registerObject("/org/freedesktop/Notifications", this); @@ -114,7 +116,7 @@ QStringList NotificationManager::GetCapabilities() { - return QStringList() << "body"; + return QStringList() << "body" << HINT_ICON << HINT_ITEM_COUNT << HINT_TIMESTAMP << HINT_PREVIEW_ICON << HINT_PREVIEW_BODY << HINT_PREVIEW_SUMMARY << "x-nemo-remote-action" << HINT_USER_REMOVABLE << "x-nemo-get-notifications"; } uint NotificationManager::Notify(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &originalHints, int expireTimeout) @@ -131,7 +133,7 @@ if (replacesId == 0) { // Create a new notification - Notification *notification = new Notification(appName, appIcon, summary, body, actions, hints, expireTimeout, this); + Notification *notification = new Notification(appName, id, appIcon, summary, body, actions, hints, expireTimeout, this); connect(notification, SIGNAL(actionInvoked(QString)), this, SLOT(invokeAction(QString))); notifications.insert(id, notification); } else { @@ -170,10 +172,10 @@ return id; } -void NotificationManager::CloseNotification(uint id) +void NotificationManager::CloseNotification(uint id, NotificationClosedReason closeReason) { if (notifications.contains(id)) { - emit NotificationClosed(id, CloseNotificationCalled); + emit NotificationClosed(id, closeReason); // Remove the notification, its actions and its hints from database execSQL(QString("DELETE FROM notifications WHERE id=?"), QVariantList() << id); @@ -195,6 +197,18 @@ return QString(); } +QList<Notification> NotificationManager::GetNotifications(const QString &appName) +{ + QList<Notification> notificationList; + foreach (uint id, notifications.keys()) { + Notification *notification = notifications.value(id); + if (notification->appName() == appName) { + notificationList.append(*notification); + } + } + return notificationList; +} + uint NotificationManager::nextAvailableNotificationID() { bool idIncreased = false; @@ -412,7 +426,7 @@ QString summary = notificationsQuery.value(notificationsTableSummaryFieldIndex).toString(); QString body = notificationsQuery.value(notificationsTableBodyFieldIndex).toString(); int expireTimeout = notificationsQuery.value(notificationsTableExpireTimeoutFieldIndex).toInt(); - Notification *notification = new Notification(appName, appIcon, summary, body, actions[id], hints[id], expireTimeout, this); + Notification *notification = new Notification(appName, id, appIcon, summary, body, actions[id], hints[id], expireTimeout, this); connect(notification, SIGNAL(actionInvoked(QString)), this, SLOT(invokeAction(QString))); notifications.insert(id, notification); @@ -465,16 +479,28 @@ void NotificationManager::invokeAction(const QString &action) { Notification *notification = qobject_cast<Notification *>(sender()); - if (notification != 0 && notification->actions().contains(action)) { + if (notification != 0) { uint id = notifications.key(notification, 0); if (id > 0) { - NOTIFICATIONS_DEBUG("INVOKE: " << action << id); - emit ActionInvoked(id, action); + QString remoteAction = notification->hints().value(QString(HINT_REMOTE_ACTION_PREFIX) + action).toString(); + if (!remoteAction.isEmpty()) { + // If a remote action has been defined for the given action, trigger it + MRemoteAction(remoteAction).trigger(); + } + + for (int actionIndex = 0; actionIndex < notification->actions().count() / 2; actionIndex++) { + // Actions are sent over as a list of pairs. Each even element in the list (starting at index 0) represents the identifier for the action. Each odd element in the list is the localized string that will be displayed to the user. + if (notification->actions().at(actionIndex * 2) == action) { + NOTIFICATIONS_DEBUG("INVOKE:" << action << id); + + emit ActionInvoked(id, action); + } + } QVariant userRemovable = notification->hints().value(HINT_USER_REMOVABLE); if (!userRemovable.isValid() || userRemovable.toBool()) { // The notification should be closed if user removability is not defined (defaults to true) or is set to true - CloseNotification(id); + CloseNotification(id, NotificationDismissedByUser); } } } --- src/notifications/notificationmanager.h +++ src/notifications/notificationmanager.h @@ -25,7 +25,35 @@ class QSqlDatabase; /*! - * The notification manager allows applications to display notifications to the user. + * \class NotificationManager + * + * \brief The notification manager allows applications to display notifications to the user. + * + * The notification manager implements a desktop notifications service based + * on the <a href="http://www.galago-project.org/specs/notification/0.9/">Desktop Notifications Specification</a>. + * The service is registered as org.freedesktop.Notifications on the D-Bus + * session bus in the path /org/freedesktop/Notifications. + * + * Notes specific to the behavior of this particular implementation: + * - The service implements the "body" capability which allows notifications + * to contain body text. + * - The "category" hint is used to load a definition for notifications in + * that category from + * /usr/share/nemo/notifications/categories/categoryname.conf. This allows + * defining common properties for all notifications in each category. + * - Each category definition file contains a list of hint=value pairs, + * one per line. + * - Each hint=value pair in the category definition file is added to + * the hints of the notification. + * - The service supports the following Nemo specific hints: + * - x-nemo-icon: icon ID for the notification. + * - x-nemo-item-count: the number of items represented by this notification. For example, a single notification can represent 4 missed calls. + * - x-nemo-timestamp: the timestamp for the notification. Should be set to the time when the event the notification is related to has occurred, not when the notification itself was sent. + * - x-nemo-preview-icon: icon ID to use in the preview banner for the notification, if any. + * - x-nemo-preview-body: body text to be shown in the preview banner for the notification, if any. + * - x-nemo-preview-summary: summary text to be shown in the preview banner for the notification, if any. + * - x-nemo-user-removable: a boolean value for defining whether the user should be able to remove the notification by tapping on it or should it be only programmatically removable. Defaults to true. + * - x-nemo-remote-action-actionname: details of the D-Bus call to be made when the action "actionname" is executed. Should be in MRemoteAction's "serviceName objectPath interface methodName" format. */ class LIPSTICK_EXPORT NotificationManager : public QObject { @@ -56,9 +84,6 @@ //! Standard hint: Specifies the Y location on the screen that the notification should point to. The "x" hint must also be specified. static const char *HINT_Y; - //! Nemo hint: Class of the notification (application/system). - static const char *HINT_CLASS; - //! Nemo hint: Icon of the notification. static const char *HINT_ICON; @@ -77,15 +102,12 @@ //! Nemo hint: Summary text of the preview of the notification. static const char *HINT_PREVIEW_SUMMARY; + //! Nemo hint: Remote action of the notification. Prefix only: the action identifier is to be appended. + static const char *HINT_REMOTE_ACTION_PREFIX; + //! Nemo hint: User removability of the notification. static const char *HINT_USER_REMOVABLE; - //! Nemo hint: Translation ID for the generic text of the notification. - static const char *HINT_GENERIC_TEXT_TRANSLATION_ID; - - //! Nemo hint: Translation catalogue name for the generic text of the notification. - static const char *HINT_GENERIC_TEXT_TRANSLATION_CATALOGUE; - //! Notifation closing reasons used in the NotificationClosed signal enum NotificationClosedReason { //! The notification expired. @@ -149,7 +171,7 @@ * * \param id the ID of the notification to be closed */ - void CloseNotification(uint id); + void CloseNotification(uint id, NotificationClosedReason closeReason = CloseNotificationCalled); /*! * This message returns the information on the server. Specifically, the server name, vendor, @@ -162,6 +184,14 @@ */ QString GetServerInformation(QString &name, QString &vendor, QString &version); + /*! + * Returns the notifications sent by a specified application. + * + * \param appName the name of the application to get notifications for + * \return a list of notifications for the application + */ + QList<Notification> GetNotifications(const QString &appName); + signals: /*! * A completed notification is one that has timed out, or has been dismissed by the user. --- src/notifications/notificationmanager.xml +++ src/notifications/notificationmanager.xml @@ -1,6 +1,7 @@ <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="org.freedesktop.Notifications"> + <!-- Desktop Notification Specification interface --> <method name="GetCapabilities"> <arg name="capabilities" type="as" direction="out"/> </method> @@ -33,5 +34,12 @@ <arg name="id" type="u"/> <arg name="action_key" type="s"/> </signal> + + <!-- Nemo extensions --> + <method name="GetNotifications"> + <arg name="app_name" type="s" direction="in"/> + <arg name="notifications" type="a(sussasa{sv}i)" direction="out"/> + <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList < Notification > "/> + </method> </interface> </node> --- src/utilities/qobjectlistmodel.cpp +++ src/utilities/qobjectlistmodel.cpp @@ -115,7 +115,7 @@ emit itemCountChanged(); } -QObject* QObjectListModel::getItem(int index) +QObject* QObjectListModel::get(int index) { if (index >= _list->count() || index < 0) return 0; @@ -143,3 +143,16 @@ QAbstractListModel::reset(); emit itemCountChanged(); } + +void QObjectListModel::move(int oldRow, int newRow) +{ + if (oldRow < 0 || oldRow >= _list->count()) + return; + + if (newRow < 0 || newRow >= _list->count()) + return; + + beginMoveRows(QModelIndex(), oldRow, oldRow, QModelIndex(), (newRow > oldRow) ? (newRow + 1) : newRow); + _list->move(oldRow, newRow); + endMoveRows(); +} --- src/utilities/qobjectlistmodel.h +++ src/utilities/qobjectlistmodel.h @@ -36,11 +36,12 @@ QVariant data(const QModelIndex &index, int role) const; bool setData(const QModelIndex &index, const QVariant &value, int role); Q_INVOKABLE void reset(); + Q_INVOKABLE void move(int oldRow, int newRow); void addItem(QObject *item); void removeItem(QObject *item); void removeItem(int index); - QObject* getItem(int index); + Q_INVOKABLE QObject* get(int index); int indexOf(QObject *obj) const; template<typename T> --- tests/stubs/notificationmanager_stub.h +++ tests/stubs/notificationmanager_stub.h @@ -29,7 +29,7 @@ virtual QList<uint> notificationIds() const; virtual QStringList GetCapabilities(); virtual uint Notify(const QString &appName, uint replacesId, const QString &appIcon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expireTimeout); - virtual void CloseNotification(uint id); + virtual void CloseNotification(uint id, NotificationManager::NotificationClosedReason closeReason); virtual QString GetServerInformation(QString &name, QString &vendor, QString &version); virtual void removeNotificationsWithCategory(const QString &category); virtual void updateNotificationsWithCategory(const QString &category); @@ -76,9 +76,10 @@ return stubReturnValue<uint>("Notify"); } -void NotificationManagerStub::CloseNotification(uint id) { +void NotificationManagerStub::CloseNotification(uint id, NotificationManager::NotificationClosedReason closeReason) { QList<ParameterBase*> params; params.append( new Parameter<uint >(id)); + params.append( new Parameter<NotificationManager::NotificationClosedReason >(closeReason)); stubMethodEntered("CloseNotification",params); } @@ -129,7 +130,6 @@ // 4. CREATE A PROXY WHICH CALLS THE STUB -const char *NotificationManager::HINT_CLASS = "x-nemo-class"; const char *NotificationManager::HINT_ICON = "x-nemo-icon"; const char *NotificationManager::HINT_TIMESTAMP = "x-nemo-timestamp"; @@ -157,8 +157,8 @@ return gNotificationManagerStub->Notify(appName, replacesId, appIcon, summary, body, actions, hints, expireTimeout); } -void NotificationManager::CloseNotification(uint id) { - gNotificationManagerStub->CloseNotification(id); +void NotificationManager::CloseNotification(uint id, NotificationClosedReason closeReason) { + gNotificationManagerStub->CloseNotification(id, closeReason); } QString NotificationManager::GetServerInformation(QString &name, QString &vendor, QString &version) { --- tests/stubs/notificationmanageradaptor_stub.h +++ tests/stubs/notificationmanageradaptor_stub.h @@ -29,7 +29,8 @@ virtual QStringList GetCapabilities(); virtual QString GetServerInformation(QString &name, QString &vendor, QString &version); virtual uint Notify(const QString &app_name, uint replaces_id, const QString &app_icon, const QString &summary, const QString &body, const QStringList &actions, const QVariantHash &hints, int expire_timeout); -}; + virtual QList<Notification> GetNotifications(const QString &app_name); +}; // 2. IMPLEMENT STUB void NotificationManagerAdaptorStub::NotificationManagerAdaptorConstructor(NotificationManager *parent) { @@ -73,6 +74,13 @@ return stubReturnValue<uint>("Notify"); } +QList<Notification> NotificationManagerAdaptorStub::GetNotifications(const QString &app_name) { + QList<ParameterBase*> params; + params.append( new Parameter<QString >(app_name)); + stubMethodEntered("GetNotifications",params); + return stubReturnValue<QList<Notification> >("GetNotifications"); +} + // 3. CREATE A STUB INSTANCE @@ -105,5 +113,9 @@ return gNotificationManagerAdaptorStub->Notify(app_name, replaces_id, app_icon, summary, body, actions, hints, expire_timeout); } +QList<Notification> NotificationManagerAdaptor::GetNotifications(const QString &app_name) { + return gNotificationManagerAdaptorStub->GetNotifications(app_name); +} + #endif --- tests/stubs/qdbusargument_fake.h +++ tests/stubs/qdbusargument_fake.h @@ -548,3 +548,10 @@ return *this; } +const QDBusArgument &operator>>(const QDBusArgument &a, QVariant &v) +{ + QDBusVariant dbv; + a >> dbv; + v = dbv.variant(); + return a; +} --- tests/stubs/qobjectlistmodel_stub.h +++ tests/stubs/qobjectlistmodel_stub.h @@ -30,10 +30,11 @@ virtual QVariant data(const QModelIndex &index, int role) const; virtual bool setData(const QModelIndex &index, const QVariant &value, int role); virtual void reset(); + virtual void move(int oldRow, int newRow); virtual void addItem(QObject *item); virtual void removeItem(QObject *item); virtual void removeItem(int index); - virtual QObject * getItem(int index); + virtual QObject * get(int index); virtual int indexOf(QObject *obj) const; virtual QList<QObject *> * getList(); virtual void setList(QList<QObject *> *list); @@ -86,6 +87,13 @@ stubMethodEntered("reset"); } +void QObjectListModelStub::move(int oldRow, int newRow) { + QList<ParameterBase*> params; + params.append( new Parameter<int >(oldRow)); + params.append( new Parameter<int >(newRow)); + stubMethodEntered("move",params); +} + void QObjectListModelStub::addItem(QObject *item) { QList<ParameterBase*> params; params.append( new Parameter<QObject * >(item)); @@ -104,11 +112,11 @@ stubMethodEntered("removeItem",params); } -QObject * QObjectListModelStub::getItem(int index) { +QObject * QObjectListModelStub::get(int index) { QList<ParameterBase*> params; params.append( new Parameter<int >(index)); - stubMethodEntered("getItem",params); - return stubReturnValue<QObject *>("getItem"); + stubMethodEntered("get",params); + return stubReturnValue<QObject *>("get"); } int QObjectListModelStub::indexOf(QObject *obj) const { @@ -181,8 +189,12 @@ gQObjectListModelStub->removeItem(index); } -QObject * QObjectListModel::getItem(int index) { - return gQObjectListModelStub->getItem(index); +QObject * QObjectListModel::get(int index) { + return gQObjectListModelStub->get(index); +} + +void QObjectListModel::move(int oldRow, int newRow) { + return gQObjectListModelStub->move(oldRow, newRow); } int QObjectListModel::indexOf(QObject *obj) const { --- tests/ut_categorydefinitionstore/.gitignore +++ tests/ut_categorydefinitionstore/.gitignore @@ -1 +0,0 @@ -ut_categorydefinitionstore --- tests/ut_notification/.gitignore +++ tests/ut_notification/.gitignore @@ -1 +0,0 @@ -ut_notification --- tests/ut_notification/ut_notification.cpp +++ tests/ut_notification/ut_notification.cpp @@ -14,6 +14,7 @@ ****************************************************************************/ #include <QtTest/QtTest> +#include "qdbusargument_fake.h" #include "ut_notification.h" #include "notification.h" #include "notificationmanager_stub.h" @@ -21,6 +22,7 @@ void Ut_Notification::testGettersAndSetters() { QString appName = "appName1"; + uint replacesId = 1; QString appIcon = "appIcon1"; QString summary = "summary1"; QString body = "body1"; @@ -33,8 +35,9 @@ int expireTimeout = 1; // Ensure that the constructor puts things in place - Notification notification(appName, appIcon, summary, body, actions, hints, expireTimeout); + Notification notification(appName, replacesId, appIcon, summary, body, actions, hints, expireTimeout); QCOMPARE(notification.appName(), appName); + QCOMPARE(notification.replacesId(), replacesId); QCOMPARE(notification.appIcon(), appIcon); QCOMPARE(notification.summary(), summary); QCOMPARE(notification.body(), body); @@ -75,7 +78,7 @@ void Ut_Notification::testSignals() { QVariantHash hints; - Notification notification(QString(), QString(), QString(), QString(), QStringList(), hints, 0); + Notification notification(QString(), 0, QString(), QString(), QString(), QStringList(), hints, 0); QSignalSpy summarySpy(¬ification, SIGNAL(summaryChanged())); QSignalSpy bodySpy(¬ification, SIGNAL(bodyChanged())); QSignalSpy iconSpy(¬ification, SIGNAL(iconChanged())); @@ -101,4 +104,38 @@ QCOMPARE(timestampSpy.count(), 1); } +void Ut_Notification::testSerialization() +{ + QString appName = "appName1"; + uint replacesId = 1; + QString appIcon = "appIcon1"; + QString summary = "summary1"; + QString body = "body1"; + QStringList actions = QStringList() << "action1a" << "action1b"; + QString icon = "icon1"; + QDateTime timestamp = QDateTime::currentDateTime(); + QVariantHash hints; + hints.insert(NotificationManager::HINT_ICON, icon); + hints.insert(NotificationManager::HINT_TIMESTAMP, timestamp); + int expireTimeout = 1; + + Notification n1(appName, replacesId, appIcon, summary, body, actions, hints, expireTimeout); + Notification n2; + + // Transfer a Notification from n1 to n2 by serializing it to a QDBusArgument and unserializing it + QDBusArgument arg; + arg << n1; + arg >> n2; + + QCOMPARE(n2.appName(), n1.appName()); + QCOMPARE(n2.replacesId(), n1.replacesId()); + QCOMPARE(n2.appIcon(), n1.appIcon()); + QCOMPARE(n2.summary(), n1.summary()); + QCOMPARE(n2.body(), n1.body()); + QCOMPARE(n2.actions(), n1.actions()); + QCOMPARE(n2.expireTimeout(), n1.expireTimeout()); + QCOMPARE(n2.icon(), n1.icon()); + QCOMPARE(n2.timestamp(), n1.timestamp()); +} + QTEST_MAIN(Ut_Notification) --- tests/ut_notification/ut_notification.h +++ tests/ut_notification/ut_notification.h @@ -24,6 +24,7 @@ private slots: void testGettersAndSetters(); void testSignals(); + void testSerialization(); }; #endif --- tests/ut_notification/ut_notification.pro +++ tests/ut_notification/ut_notification.pro @@ -13,4 +13,6 @@ HEADERS += \ ut_notification.h \ $$NOTIFICATIONSRCDIR/notification.h \ - $$NOTIFICATIONSRCDIR/notificationmanager.h + $$NOTIFICATIONSRCDIR/notificationmanager.h \ + qdbusargument_fake.h + --- tests/ut_notificationlistmodel/.gitignore +++ tests/ut_notificationlistmodel/.gitignore @@ -1 +0,0 @@ -ut_notificationlistmodel --- tests/ut_notificationlistmodel/ut_notificationlistmodel.cpp +++ tests/ut_notificationlistmodel/ut_notificationlistmodel.cpp @@ -31,7 +31,7 @@ void Ut_NotificationListModel::testModelPopulatesOnConstruction() { - Notification notification("appName", "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1 << 2); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", -1); @@ -43,7 +43,7 @@ void Ut_NotificationListModel::testNotificationIsOnlyAddedIfNotAlreadyAdded() { - Notification notification("appName", "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", 0); @@ -51,21 +51,9 @@ QCOMPARE(gQObjectListModelStub->stubCallCount("addItem"), 0); } -void Ut_NotificationListModel::testNotificationIsNotAddedIfClassIsSystem() -{ - QVariantHash hints; - hints.insert(NotificationManager::HINT_CLASS, "system"); - Notification notification("appName", "appIcon", "summary", "body", QStringList() << "action", hints, 1); - gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); - gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); - gQObjectListModelStub->stubSetReturnValue("indexOf", -1); - NotificationListModel model; - QCOMPARE(gQObjectListModelStub->stubCallCount("addItem"), 0); -} - void Ut_NotificationListModel::testNotificationIsNotAddedIfSummaryIsEmpty() { - Notification notification("appName", "appIcon", "", "body", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "", "body", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", -1); @@ -75,7 +63,7 @@ void Ut_NotificationListModel::testNotificationIsNotAddedIfBodyIsEmpty() { - Notification notification("appName", "appIcon", "summary", "", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "summary", "", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", -1); @@ -83,22 +71,9 @@ QCOMPARE(gQObjectListModelStub->stubCallCount("addItem"), 0); } -void Ut_NotificationListModel::testAlreadyAddedNotificationIsRemovedIfClassChangesToSystem() -{ - QVariantHash hints; - hints.insert(NotificationManager::HINT_CLASS, "system"); - Notification notification("appName", "appIcon", "summary", "body", QStringList() << "action", hints, 1); - gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); - gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); - gQObjectListModelStub->stubSetReturnValue("indexOf", 0); - NotificationListModel model; - QCOMPARE(gQObjectListModelStub->stubCallCount("removeItem"), 1); - QCOMPARE(gQObjectListModelStub->stubCallsTo("removeItem").at(0)->parameter<QObject *>(0), ¬ification); -} - void Ut_NotificationListModel::testAlreadyAddedNotificationIsRemovedIfSummaryChangesToEmpty() { - Notification notification("appName", "appIcon", "", "body", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "", "body", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", 0); @@ -109,7 +84,7 @@ void Ut_NotificationListModel::testAlreadyAddedNotificationIsRemovedIfBodyChangesToEmpty() { - Notification notification("appName", "appIcon", "summary", "", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "summary", "", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notificationIds", QList<uint>() << 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); gQObjectListModelStub->stubSetReturnValue("indexOf", 0); @@ -121,7 +96,7 @@ void Ut_NotificationListModel::testNotificationRemoval() { NotificationListModel model; - Notification notification("appName", "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); + Notification notification("appName", 1, "appIcon", "summary", "body", QStringList() << "action", QVariantHash(), 1); gNotificationManagerStub->stubSetReturnValue("notification", ¬ification); model.removeNotification(1); QCOMPARE(gQObjectListModelStub->stubCallCount("removeItem"), 1); --- tests/ut_notificationlistmodel/ut_notificationlistmodel.h +++ tests/ut_notificationlistmodel/ut_notificationlistmodel.h @@ -26,10 +26,8 @@ void cleanup(); void testModelPopulatesOnConstruction(); void testNotificationIsOnlyAddedIfNotAlreadyAdded(); - void testNotificationIsNotAddedIfClassIsSystem(); void testNotificationIsNotAddedIfSummaryIsEmpty(); void testNotificationIsNotAddedIfBodyIsEmpty(); - void testAlreadyAddedNotificationIsRemovedIfClassChangesToSystem(); void testAlreadyAddedNotificationIsRemovedIfSummaryChangesToEmpty(); void testAlreadyAddedNotificationIsRemovedIfBodyChangesToEmpty(); void testNotificationRemoval(); --- tests/ut_notificationmanager/.gitignore +++ tests/ut_notificationmanager/.gitignore @@ -1 +0,0 @@ -ut_notificationmanager --- tests/ut_notificationmanager/ut_notificationmanager.cpp +++ tests/ut_notificationmanager/ut_notificationmanager.cpp @@ -22,6 +22,7 @@ #include <QSqlTableModel> #include <QSqlRecord> #include <QSqlError> +#include <mremoteaction.h> #include <sys/statfs.h> const static uint DISK_SPACE_NEEDED = 1024; @@ -250,6 +251,13 @@ timerInterval = interval(); } +// MRemoteAction stubs +QStringList mRemoteActionTrigger; +void MRemoteAction::trigger() +{ + mRemoteActionTrigger.append(toString()); +} + void Ut_NotificationManager::init() { qSqlQueryExecQuery.clear(); @@ -267,6 +275,7 @@ qSqlDatabaseCommitCalled = false; diskSpaceAvailableKb = DISK_SPACE_NEEDED + 100; diskSpaceChecked = true; + mRemoteActionTrigger.clear(); } void Ut_NotificationManager::cleanup() @@ -318,9 +327,9 @@ QCOMPARE(qSqlQueryExecQuery.at(4), QString("CREATE TABLE actions (id INTEGER, action TEXT, PRIMARY KEY(id, action))")); QCOMPARE(qSqlQueryExecQuery.at(5), QString("DROP TABLE hints")); QCOMPARE(qSqlQueryExecQuery.at(6), QString("CREATE TABLE hints (id INTEGER, hint TEXT, value TEXT, PRIMARY KEY(id, hint))")); - QCOMPARE(modelToTableName.values().contains("notifications"), QBool(true)); - QCOMPARE(modelToTableName.values().contains("actions"), QBool(true)); - QCOMPARE(modelToTableName.values().contains("hints"), QBool(true)); + QCOMPARE((bool)modelToTableName.values().contains("notifications"), true); + QCOMPARE((bool)modelToTableName.values().contains("actions"), true); + QCOMPARE((bool)modelToTableName.values().contains("hints"), true); notificationsTableFieldIndices.clear(); actionsTableFieldIndices.clear(); hintsTableFieldIndices.clear(); @@ -369,24 +378,24 @@ notificationValues << notification1Values << notification2Values; qSqlQueryValues["SELECT * FROM notifications"].append(notificationValues); - QHash<int, QVariant> notification1Action1; - QHash<int, QVariant> notification1Action2; - QHash<int, QVariant> notification2Action1; - QHash<int, QVariant> notification2Action2; - notification1Action1.insert(0, 1); - notification1Action1.insert(1, "action1-1"); - notification1Action2.insert(0, 1); - notification1Action2.insert(1, "action1-2"); - notification2Action1.insert(0, 2); - notification2Action1.insert(1, "action2-1"); - notification2Action2.insert(0, 2); - notification2Action2.insert(1, "action2-2"); + QHash<int, QVariant> notification1ActionIdentifier; + QHash<int, QVariant> notification1ActionName; + QHash<int, QVariant> notification2ActionIdentifier; + QHash<int, QVariant> notification2ActionName; + notification1ActionIdentifier.insert(0, 1); + notification1ActionIdentifier.insert(1, "action1"); + notification1ActionName.insert(0, 1); + notification1ActionName.insert(1, "Action 1"); + notification2ActionIdentifier.insert(0, 2); + notification2ActionIdentifier.insert(1, "action2"); + notification2ActionName.insert(0, 2); + notification2ActionName.insert(1, "Action 2"); QList<QHash<int, QVariant> > notificationActions; - notificationActions << notification1Action1 << notification1Action2 << notification2Action1 << notification2Action2; + notificationActions << notification1ActionIdentifier << notification1ActionName << notification2ActionIdentifier << notification2ActionName; qSqlQueryValues["SELECT * FROM actions"].append(notificationActions); QHash<uint, QStringList> notificationActionsById; - notificationActionsById.insert(1, QStringList() << "action1-1" << "action1-2"); - notificationActionsById.insert(2, QStringList() << "action2-1" << "action2-2"); + notificationActionsById.insert(1, QStringList() << "action1" << "Action 1"); + notificationActionsById.insert(2, QStringList() << "action2" << "Action 2"); QHash<int, QVariant> notification1Hint1; QHash<int, QVariant> notification1Hint2; @@ -443,10 +452,19 @@ void Ut_NotificationManager::testCapabilities() { - // Check that "body" is the only supported capability + // Check the supported capabilities includes all the Nemo hints QStringList capabilities = NotificationManager::instance()->GetCapabilities(); - QCOMPARE(capabilities.count(), 1); - QCOMPARE(capabilities.contains("body"), QBool(true)); + QCOMPARE(capabilities.count(), 10); + QCOMPARE((bool)capabilities.contains("body"), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_ICON), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_ITEM_COUNT), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_TIMESTAMP), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_PREVIEW_ICON), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_PREVIEW_BODY), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_PREVIEW_SUMMARY), true); + QCOMPARE((bool)capabilities.contains("x-nemo-remote-action"), true); + QCOMPARE((bool)capabilities.contains(NotificationManager::HINT_USER_REMOVABLE), true); + QCOMPARE((bool)capabilities.contains("x-nemo-get-notifications"), true); } void Ut_NotificationManager::testAddingNotification() @@ -457,7 +475,7 @@ QSignalSpy spy(manager, SIGNAL(notificationModified(uint))); QVariantHash hints; hints.insert("hint", "value"); - uint id = manager->Notify("appName", 0, "appIcon", "summary", "body", QStringList() << "action1" << "action2", hints, 1); + uint id = manager->Notify("appName", 0, "appIcon", "summary", "body", QStringList() << "action" << "Action", hints, 1); Notification *notification = manager->notification(id); QCOMPARE(disconnect(notification, SIGNAL(actionInvoked(QString)), manager, SLOT(invokeAction(QString))), true); QCOMPARE(spy.count(), 1); @@ -476,9 +494,9 @@ QCOMPARE(qSqlQueryAddBindValue.at(4), QVariant("body")); QCOMPARE(qSqlQueryAddBindValue.at(5).toInt(), 1); QCOMPARE(qSqlQueryAddBindValue.at(6).toUInt(), id); - QCOMPARE(qSqlQueryAddBindValue.at(7), QVariant("action1")); + QCOMPARE(qSqlQueryAddBindValue.at(7), QVariant("action")); QCOMPARE(qSqlQueryAddBindValue.at(8).toUInt(), id); - QCOMPARE(qSqlQueryAddBindValue.at(9), QVariant("action2")); + QCOMPARE(qSqlQueryAddBindValue.at(9), QVariant("Action")); QCOMPARE(qSqlQueryAddBindValue.at(10).toUInt(), id); QCOMPARE(qSqlQueryAddBindValue.at(11), QVariant("hint")); QCOMPARE(qSqlQueryAddBindValue.at(12), QVariant("value")); @@ -490,8 +508,8 @@ QCOMPARE(notification->summary(), QString("summary")); QCOMPARE(notification->body(), QString("body")); QCOMPARE(notification->actions().count(), 2); - QCOMPARE(notification->actions().at(0), QString("action1")); - QCOMPARE(notification->actions().at(1), QString("action2")); + QCOMPARE(notification->actions().at(0), QString("action")); + QCOMPARE(notification->actions().at(1), QString("Action")); QCOMPARE(notification->hints().value("hint"), QVariant("value")); QCOMPARE(notification->hints().value(NotificationManager::HINT_TIMESTAMP).type(), QVariant::DateTime); } @@ -646,12 +664,12 @@ QCOMPARE(manager->notification(id2), (Notification *)0); } -void Ut_NotificationManager::testActionIsInvokedIfActionIsDefined() +void Ut_NotificationManager::testActionIsInvokedIfDefined() { // Add two notifications, only the first one with an action named "action1" NotificationManager *manager = NotificationManager::instance(); - uint id1 = manager->Notify("app1", 0, QString(), QString(), QString(), QStringList() << "action1", QVariantHash(), 0); - uint id2 = manager->Notify("app2", 0, QString(), QString(), QString(), QStringList() << "action2", QVariantHash(), 0); + uint id1 = manager->Notify("app1", 0, QString(), QString(), QString(), QStringList() << "action1" << "Action 1", QVariantHash(), 0); + uint id2 = manager->Notify("app2", 0, QString(), QString(), QString(), QStringList() << "action2" << "Action 2", QVariantHash(), 0); Notification *notification1 = manager->notification(id1); Notification *notification2 = manager->notification(id2); connect(this, SIGNAL(actionInvoked(QString)), notification1, SIGNAL(actionInvoked(QString))); @@ -665,6 +683,39 @@ QCOMPARE(spy.last().at(1).toString(), QString("action1")); } +void Ut_NotificationManager::testActionIsNotInvokedIfIncomplete() +{ + // Add two notifications, the first one with an incomplete action named "action1" + NotificationManager *manager = NotificationManager::instance(); + uint id1 = manager->Notify("app1", 0, QString(), QString(), QString(), QStringList() << "action1", QVariantHash(), 0); + uint id2 = manager->Notify("app2", 0, QString(), QString(), QString(), QStringList() << "action2" << "Action 2", QVariantHash(), 0); + Notification *notification1 = manager->notification(id1); + Notification *notification2 = manager->notification(id2); + connect(this, SIGNAL(actionInvoked(QString)), notification1, SIGNAL(actionInvoked(QString))); + connect(this, SIGNAL(actionInvoked(QString)), notification2, SIGNAL(actionInvoked(QString))); + + // Make both notifications emit the actionInvoked() signal for action "action1"; no action should be invoked + QSignalSpy spy(manager, SIGNAL(ActionInvoked(uint, QString))); + emit actionInvoked("action1"); + QCOMPARE(spy.count(), 0); +} + +void Ut_NotificationManager::testRemoteActionIsInvokedIfDefined() +{ + // Add a notifications with an action named "action" + NotificationManager *manager = NotificationManager::instance(); + QVariantHash hints; + hints.insert(QString(NotificationManager::HINT_REMOTE_ACTION_PREFIX) + "action", "a b c d"); + uint id = manager->Notify("app", 0, QString(), QString(), QString(), QStringList(), hints, 0); + Notification *notification = manager->notification(id); + connect(this, SIGNAL(actionInvoked(QString)), notification, SIGNAL(actionInvoked(QString))); + + // Invoking the notification should trigger the remote action + emit actionInvoked("action"); + QCOMPARE(mRemoteActionTrigger.count(), 1); + QCOMPARE(mRemoteActionTrigger.last(), hints.value(QString(NotificationManager::HINT_REMOTE_ACTION_PREFIX) + "action").toString()); +} + void Ut_NotificationManager::testInvokingActionRemovesNotificationIfUserRemovable() { // Add three notifications with user removability not set, set to true and set to false @@ -674,9 +725,9 @@ QVariantHash hints3; hints2.insert(NotificationManager::HINT_USER_REMOVABLE, true); hints3.insert(NotificationManager::HINT_USER_REMOVABLE, false); - uint id1 = manager->Notify("app1", 0, QString(), QString(), QString(), QStringList() << "action", hints1, 0); - uint id2 = manager->Notify("app2", 0, QString(), QString(), QString(), QStringList() << "action", hints2, 0); - uint id3 = manager->Notify("app3", 0, QString(), QString(), QString(), QStringList() << "action", hints3, 0); + uint id1 = manager->Notify("app1", 0, QString(), QString(), QString(), QStringList(), hints1, 0); + uint id2 = manager->Notify("app2", 0, QString(), QString(), QString(), QStringList(), hints2, 0); + uint id3 = manager->Notify("app3", 0, QString(), QString(), QString(), QStringList(), hints3, 0); Notification *notification1 = manager->notification(id1); Notification *notification2 = manager->notification(id2); Notification *notification3 = manager->notification(id3); @@ -685,11 +736,64 @@ connect(this, SIGNAL(actionInvoked(QString)), notification3, SIGNAL(actionInvoked(QString))); // Make all notifications emit the actionInvoked() signal for action "action"; removable notifications should get removed - QSignalSpy spy(manager, SIGNAL(notificationRemoved(uint))); + QSignalSpy removedSpy(manager, SIGNAL(notificationRemoved(uint))); + QSignalSpy closedSpy(manager, SIGNAL(NotificationClosed(uint,uint))); emit actionInvoked("action"); - QCOMPARE(spy.count(), 2); - QCOMPARE(spy.at(0).at(0).toUInt(), id1); - QCOMPARE(spy.at(1).at(0).toUInt(), id2); + QCOMPARE(removedSpy.count(), 2); + QCOMPARE(removedSpy.at(0).at(0).toUInt(), id1); + QCOMPARE(removedSpy.at(1).at(0).toUInt(), id2); + QCOMPARE(closedSpy.count(), 2); + QCOMPARE(closedSpy.at(0).at(0).toUInt(), id1); + QCOMPARE(closedSpy.at(0).at(1).toInt(), (int)NotificationManager::NotificationDismissedByUser); + QCOMPARE(closedSpy.at(1).at(0).toUInt(), id2); + QCOMPARE(closedSpy.at(1).at(1).toInt(), (int)NotificationManager::NotificationDismissedByUser); +} + +void Ut_NotificationManager::testListingNotifications() +{ + NotificationManager *manager = NotificationManager::instance(); + + // Add three notifications, two for application appName1 and one for appName2 + QVariantHash hints1; + QVariantHash hints2; + QVariantHash hints3; + hints1.insert(NotificationManager::HINT_CATEGORY, "category1"); + hints2.insert(NotificationManager::HINT_CATEGORY, "category2"); + hints3.insert(NotificationManager::HINT_CATEGORY, "category3"); + uint id1 = manager->Notify("appName1", 0, "appIcon1", "summary1", "body1", QStringList() << "action1", hints1, 1); + uint id2 = manager->Notify("appName1", 0, "appIcon2", "summary2", "body2", QStringList() << "action2", hints2, 2); + uint id3 = manager->Notify("appName2", 0, "appIcon3", "summary3", "body3", QStringList() << "action3", hints3, 3); + + // Check that only notifications for the given application are returned and that they contain all the information + QList<Notification> notifications = manager->GetNotifications("appName1"); + QCOMPARE(notifications.count(), 2); + QCOMPARE(notifications.at(0).appName(), QString("appName1")); + QCOMPARE(notifications.at(1).appName(), QString("appName1")); + QCOMPARE(notifications.at(0).replacesId(), id1); + QCOMPARE(notifications.at(1).replacesId(), id2); + QCOMPARE(notifications.at(0).appIcon(), QString("appIcon1")); + QCOMPARE(notifications.at(1).appIcon(), QString("appIcon2")); + QCOMPARE(notifications.at(0).summary(), QString("summary1")); + QCOMPARE(notifications.at(1).summary(), QString("summary2")); + QCOMPARE(notifications.at(0).body(), QString("body1")); + QCOMPARE(notifications.at(1).body(), QString("body2")); + QCOMPARE(notifications.at(0).actions(), QStringList() << "action1"); + QCOMPARE(notifications.at(1).actions(), QStringList() << "action2"); + QCOMPARE(notifications.at(0).hints().value(NotificationManager::HINT_CATEGORY), QVariant("category1")); + QCOMPARE(notifications.at(1).hints().value(NotificationManager::HINT_CATEGORY), QVariant("category2")); + QCOMPARE(notifications.at(0).expireTimeout(), 1); + QCOMPARE(notifications.at(1).expireTimeout(), 2); + + notifications = manager->GetNotifications("appName2"); + QCOMPARE(notifications.count(), 1); + QCOMPARE(notifications.at(0).appName(), QString("appName2")); + QCOMPARE(notifications.at(0).replacesId(), id3); + QCOMPARE(notifications.at(0).appIcon(), QString("appIcon3")); + QCOMPARE(notifications.at(0).summary(), QString("summary3")); + QCOMPARE(notifications.at(0).body(), QString("body3")); + QCOMPARE(notifications.at(0).actions(), QStringList() << "action3"); + QCOMPARE(notifications.at(0).hints().value(NotificationManager::HINT_CATEGORY), QVariant("category3")); + QCOMPARE(notifications.at(0).expireTimeout(), 3); } QTEST_MAIN(Ut_NotificationManager) --- tests/ut_notificationmanager/ut_notificationmanager.h +++ tests/ut_notificationmanager/ut_notificationmanager.h @@ -40,8 +40,11 @@ void testServerInformation(); void testModifyingCategoryDefinitionUpdatesNotifications(); void testUninstallingCategoryDefinitionRemovesNotifications(); - void testActionIsInvokedIfActionIsDefined(); + void testActionIsInvokedIfDefined(); + void testActionIsNotInvokedIfIncomplete(); + void testRemoteActionIsInvokedIfDefined(); void testInvokingActionRemovesNotificationIfUserRemovable(); + void testListingNotifications(); signals: void actionInvoked(QString action); --- tests/ut_notificationmanager/ut_notificationmanager.pro +++ tests/ut_notificationmanager/ut_notificationmanager.pro @@ -1,7 +1,9 @@ include(../common.pri) TARGET = ut_notificationmanager INCLUDEPATH += $$NOTIFICATIONSRCDIR +CONFIG += link_pkgconfig QT += sql dbus +PKGCONFIG += mlite # unit test and unit SOURCES += \ --- tools/notificationtool/.gitignore +++ tools/notificationtool/.gitignore @@ -1,2 +0,0 @@ -notificationmanagerproxy.* -notificationtool --- tools/notificationtool/notificationtool.pro +++ tools/notificationtool/notificationtool.pro @@ -1,4 +1,4 @@ -system(qdbusxml2cpp ../../src/notifications/notificationmanager.xml -p notificationmanagerproxy -c NotificationManagerProxy) +system(qdbusxml2cpp ../../src/notifications/notificationmanager.xml -p notificationmanagerproxy -c NotificationManagerProxy -i notification.h) TEMPLATE = app TARGET = notificationtool ++++++ lipstick.yaml --- lipstick.yaml +++ lipstick.yaml @@ -1,6 +1,6 @@ Name: lipstick Summary: QML toolkit for homescreen creation -Version: 0.4.1 +Version: 0.4.2 Release: 1 Group: System/Libraries License: LGPLv2.1 @@ -14,7 +14,7 @@ - QtDeclarative - QtSensors - contentaction-0.1 - - mlite + - mlite >= 0.0.6 - xcomposite - xdamage Files:
