on xenial help sign in
Still broken notification-qmltest due to heavily extended MockNotification-plugin.
commit44c803d9a243bbff0693a5cf602c0836145658c6 authorMirco Müller <mirco.mueller@canonical.com> dateMon 1 Dec 2014, 16:10 (12 years ago) parent5a54cb7
5 files changed+320−103
qml/Notifications/Notification.qml+5−5 tests/mocks/Unity/Notifications/MockNotificationTypes.cpp+149−1 tests/mocks/Unity/Notifications/MockNotificationTypes.h+58−1 tests/mocks/Unity/Notifications/plugin.cpp+1−1 tests/qmltests/Notifications/tst_Notifications.qml+107−95
qml/Notifications/Notification.qml+5−5
@@ -81,12 +81,12 @@ Item {
8181 id: sound
8282 objectName: "sound"
8383 audioRole: MediaPlayer.alert
84− source: hints["suppress-sound"] != "true" && hints["sound-file"] != undefined ? hints["sound-file"] : ""
84+ source: hints["suppress-sound"] !== "true" && hints["sound-file"] !== undefined ? hints["sound-file"] : ""
8585 }
8686
8787 // FIXME: using onCompleted because of LP: #1354406 workaround, has to be onOpacityChanged really
8888 Component.onCompleted: {
89− if (opacity == 1.0 && hints["suppress-sound"] != "true" && sound.source != "") {
89+ if (opacity == 1.0 && hints["suppress-sound"] !== "true" && sound.source !== "") {
9090 sound.play();
9191 }
9292 }
@@ -102,7 +102,7 @@ Item {
102102 }
103103
104104 onHintsChanged: {
105− if (type === Notification.Confirmation && opacity == 1.0 && hints["suppress-sound"] != "true" && sound.source != "") {
105+ if (type === Notification.Confirmation && opacity == 1.0 && hints["suppress-sound"] !== "true" && sound.source !== "") {
106106 sound.play();
107107 }
108108 }
@@ -159,7 +159,7 @@ Item {
159159
160160 onXChanged: {
161161 if (draggable && notification.x > 0.75 * notification.width) {
162− notification.notification.close(notificationId)
162+ notification.notification.close()
163163 }
164164 }
165165
@@ -187,7 +187,7 @@ Item {
187187 menuObjectPath: paths.menuObjectPath
188188 onNameOwnerChanged: {
189189 if (lastNameOwner != "" && nameOwner == "" && notification.notification != undefined) {
190− notification.notification.close(notificationId)
190+ notification.notification.close()
191191 }
192192 lastNameOwner = nameOwner
193193 }
tests/mocks/Unity/Notifications/MockNotificationTypes.cpp+149−1
@@ -19,8 +19,156 @@
1919
2020#include "MockNotificationTypes.h"
2121
22−MockNotification::MockNotification(QObject *parent) : QObject(parent) {
22+struct MockNotificationPrivate {
23+ unsigned int nid;
24+ QString summary;
25+ QString body;
26+ int value;
27+ MockNotification::Type type;
28+ QString icon;
29+ QString secondaryIcon;
30+ QStringList actions;
31+ ActionModel* actionsModel;
32+ QVariantMap hints;
33+};
34+
35+MockNotification::MockNotification(QObject *parent) : QObject(parent), p(new MockNotificationPrivate()) {
2336}
2437
2538MockNotification::~MockNotification() {
2639}
40+
41+QString MockNotification::getSummary() const {
42+ return p->summary;
43+}
44+
45+void MockNotification::setSummary(const QString &summary) {
46+ if(p->summary != summary) {
47+ p->summary= summary;
48+ Q_EMIT summaryChanged(p->summary);
49+ Q_EMIT dataChanged(p->nid);
50+ }
51+}
52+
53+QString MockNotification::getBody() const {
54+ return p->body;
55+}
56+
57+void MockNotification::setBody(const QString &body) {
58+ if(p->body != body) {
59+ p->body = body;
60+ Q_EMIT bodyChanged(p->body);
61+ Q_EMIT dataChanged(p->nid);
62+ }
63+}
64+
65+unsigned int MockNotification::getNID() const {
66+ return p->nid;
67+}
68+
69+void MockNotification::setNID(const unsigned int nid) {
70+ p->nid = nid;
71+}
72+
73+int MockNotification::getValue() const {
74+ return p->value;
75+}
76+
77+void MockNotification::setValue(int value) {
78+ if(p->value != value) {
79+ p->value = value;
80+ Q_EMIT valueChanged(p->value);
81+ Q_EMIT dataChanged(p->nid);
82+ }
83+}
84+
85+QString MockNotification::getIcon() const {
86+ return p->icon;
87+}
88+
89+void MockNotification::setIcon(const QString &icon) {
90+ if (icon.startsWith(" ") || icon.size() == 0) {
91+ p->icon = nullptr;
92+ }
93+ else {
94+ p->icon = icon;
95+
96+ if (icon.indexOf("/") == -1) {
97+ p->icon.prepend("image://theme/");
98+ }
99+ }
100+
101+ Q_EMIT iconChanged(p->icon);
102+ Q_EMIT dataChanged(p->nid);
103+}
104+
105+QString MockNotification::getSecondaryIcon() const {
106+ return p->secondaryIcon;
107+}
108+
109+void MockNotification::setSecondaryIcon(const QString &secondaryIcon) {
110+ if (secondaryIcon.startsWith(" ") || secondaryIcon.size() == 0) {
111+ p->secondaryIcon = nullptr;
112+ }
113+ else {
114+ p->secondaryIcon = secondaryIcon;
115+
116+ if (secondaryIcon.indexOf("/") == -1) {
117+ p->secondaryIcon.prepend("image://theme/");
118+ }
119+ }
120+
121+ Q_EMIT secondaryIconChanged(p->secondaryIcon);
122+ Q_EMIT dataChanged(p->nid);
123+}
124+
125+MockNotification::Type MockNotification::getType() const {
126+ return p->type;
127+}
128+
129+void MockNotification::setType(Type type) {
130+ if(p->type != p->type) {
131+ p->type = type;
132+ Q_EMIT typeChanged(p->type);
133+ }
134+}
135+
136+ActionModel* MockNotification::getActions() const {
137+ return p->actionsModel;
138+}
139+
140+void MockNotification::setActions(const QStringList &actions) {
141+ if(p->actions != actions) {
142+ p->actions = actions;
143+ Q_EMIT actionsChanged(p->actions);
144+
145+ for (int i = 0; i < p->actions.size(); i += 2) {
146+ p->actionsModel->insertAction(p->actions[i], p->actions[i+1]);
147+ }
148+ }
149+}
150+
151+QVariantMap MockNotification::getHints() const {
152+ return p->hints;
153+}
154+
155+void MockNotification::setHints(const QVariantMap& hints) {
156+ if (p->hints != hints) {
157+ p->hints = hints;
158+ Q_EMIT hintsChanged(p->hints);
159+ }
160+}
161+
162+void MockNotification::invokeAction(const QString &action) {
163+ for(int i=0; i<p->actions.size(); i++) {
164+ if(p->actions[i] == action) {
165+ Q_EMIT completed(p->nid);
166+ return;
167+ }
168+ }
169+ fprintf(stderr, "Error: tried to invoke action not in actionList.\n");
170+}
171+
172+void MockNotification::close() {
173+ Q_EMIT completed(p->nid);
174+}
tests/mocks/Unity/Notifications/MockNotificationTypes.h+58−1
@@ -20,17 +20,74 @@
2020#ifndef MOCK_NOTIFICATION_TYPES_H
2121#define MOCK_NOTIFICATION_TYPES_H
2222
23+#include "MockActionModel.h"
2324#include <QObject>
25+#include <QString>
26+#include <QStringList>
27+#include <QScopedPointer>
28+
29+struct MockNotificationPrivate;
2430
2531class MockNotification : public QObject {
2632 Q_OBJECT
2733 Q_ENUMS(Type)
34+ Q_PROPERTY(QString summary READ getSummary WRITE setSummary NOTIFY summaryChanged)
35+ Q_PROPERTY(QString body READ getBody WRITE setBody NOTIFY bodyChanged)
36+ Q_PROPERTY(unsigned int nid READ getNID WRITE setNID NOTIFY nidChanged)
37+ Q_PROPERTY(int value READ getValue WRITE setValue NOTIFY valueChanged)
38+ Q_PROPERTY(QString icon READ getIcon WRITE setIcon NOTIFY iconChanged)
39+ Q_PROPERTY(QString secondaryIcon READ getSecondaryIcon WRITE setSecondaryIcon NOTIFY secondaryIconChanged)
40+ Q_PROPERTY(Type type READ getType WRITE setType NOTIFY typeChanged)
41+ Q_PROPERTY(QStringList rawActions WRITE setActions)
42+ Q_PROPERTY(ActionModel* actions READ getActions NOTIFY actionsChanged)
43+ Q_PROPERTY(QVariantMap hints READ getHints WRITE setHints NOTIFY hintsChanged)
44+
45+private:
46+ QScopedPointer<MockNotificationPrivate> p;
47+
48+public:
49+ enum Urgency { Low, Normal, Critical };
50+ enum Type { PlaceHolder, Confirmation, Ephemeral, Interactive, SnapDecision };
51+
52+Q_SIGNALS:
53+ void summaryChanged(const QString &summary);
54+ void bodyChanged(const QString &body);
55+ void nidChanged(const unsigned int nid);
56+ void valueChanged(int value);
57+ void iconChanged(const QString &icon);
58+ void secondaryIconChanged(const QString &secondaryIcon);
59+ void typeChanged(Type type);
60+ void actionsChanged(const QStringList &actions);
61+ void hintsChanged(const QVariantMap& hints);
62+
63+ void dataChanged(unsigned int nid);
64+ void completed(unsigned int nid);
2865
2966public:
3067 MockNotification(QObject *parent=nullptr);
3168 virtual ~MockNotification();
3269
33− enum Type { PlaceHolder, Confirmation, Ephemeral, Interactive, SnapDecision };
70+ QString getSummary() const;
71+ void setSummary(const QString &summary);
72+ QString getBody() const;
73+ void setBody(const QString &body);
74+ unsigned int getNID() const;
75+ void setNID(const unsigned int nid);
76+ int getValue() const;
77+ void setValue(int value);
78+ QString getIcon() const;
79+ void setIcon(const QString &icon);
80+ QString getSecondaryIcon() const;
81+ void setSecondaryIcon(const QString &secondaryIcon);
82+ Type getType() const;
83+ void setType(Type type);
84+ ActionModel* getActions() const;
85+ void setActions(const QStringList &actions);
86+ QVariantMap getHints() const;
87+ void setHints(const QVariantMap& hints);
88+
89+ Q_INVOKABLE void invokeAction(const QString &action);
90+ Q_INVOKABLE void close();
3491};
3592
3693#endif // MOCK_NOTIFICATION_TYPES_H
tests/mocks/Unity/Notifications/plugin.cpp+1−1
@@ -26,6 +26,6 @@
2626void TestNotificationPlugin::registerTypes(const char* uri)
2727{
2828 // @uri Unity.Notifications
29− qmlRegisterUncreatableType<MockNotification>(uri, 1, 0, "Notification", "Notification objects can only be created by the plugin");
29+ qmlRegisterType<MockNotification>(uri, 1, 0, "Notification");
3030 qmlRegisterType<ActionModel>(uri, 1, 0, "ActionModel");
3131}
tests/qmltests/Notifications/tst_Notifications.qml+107−95
@@ -30,7 +30,7 @@ Item {
3030 Row {
3131 id: rootRow
3232
33− Component {
33+ /*Component {
3434 id: mockNotification
3535
3636 QtObject {
@@ -46,6 +46,18 @@ Item {
4646 }
4747 }
4848 }
49+ }*/
50+
51+ Notification {
52+ id: mockNotificationDefault
53+ type: Notification.PlaceHolder
54+ //nid: 1 //mockModel.getNextId()
55+ hints: {}
56+ summary: ""
57+ body: ""
58+ icon: ""
59+ secondaryIcon: ""
60+ rawActions: [{ id: "reply_id", label: "Dummy"}]
4961 }
5062
5163 ListModel {
@@ -60,132 +72,132 @@ Item {
6072 }
6173
6274 function getRaw(id) {
63− return mockNotification.createObject(mockModel)
75+ for (var i = 0; i < mockModel.count; i++) {
76+ if (id === mockModel.get(i).nid) {
77+ return mockModel.get(i).notification
78+ }
79+ }
6480 }
6581
6682 // add the default/PlaceHolder notification to the model
6783 Component.onCompleted: {
68− var n = {
69− type: Notification.PlaceHolder,
70− id: mockModel.getNextId(),
71− hints: {},
72− summary: "",
73− body: "",
74− icon: "",
75− secondaryIcon: "",
76− actions: []
77− }
78−
79− append(n)
84+ append(mockNotificationDefault)
8085 }
8186 }
8287
88+ Notification {
89+ id: mock2over1SnapDecisionNotification
90+ type: Notification.SnapDecision
91+ //nid: 2 //mockModel.getNextId()
92+ hints: {"x-canonical-private-affirmative-tint": "true"}
93+ summary: "Theatre at Ferria Stadium"
94+ body: "at Ferria Stadium in Bilbao, Spain\n07578545317"
95+ icon: ""
96+ secondaryIcon: ""
97+ rawActions: [{ id: "ok_id", label: "Ok"},
98+ { id: "snooze_id", label: "Snooze"},
99+ { id: "view_id", label: "View"}]
100+ }
101+
83102 function add2over1SnapDecisionNotification() {
84− var n = {
85− type: Notification.SnapDecision,
86− id: mockModel.getNextId(),
87− hints: {"x-canonical-private-affirmative-tint": "true"},
88− summary: "Theatre at Ferria Stadium",
89− body: "at Ferria Stadium in Bilbao, Spain\n07578545317",
90− icon: "",
91− secondaryIcon: "",
92− actions: [{ id: "ok_id", label: "Ok"},
93− { id: "snooze_id", label: "Snooze"},
94− { id: "view_id", label: "View"}]
95− }
103+ mockModel.append(mock2over1SnapDecisionNotification)
104+ }
96105
97− mockModel.append(n)
106+ Notification {
107+ id: mockEphemeralNotification
108+ type: Notification.Ephemeral
109+ //nid: 3 //mockModel.getNextId()
110+ summary: "Cole Raby"
111+ body: "I did not expect it to be that late."
112+ icon: "../graphics/avatars/amanda.png"
113+ secondaryIcon: "../graphics/applicationIcons/facebook.png"
114+ rawActions: [{ id: "reply_id", label: "Dummy"}]
98115 }
99116
100117 function addEphemeralNotification() {
101− var n = {
102− type: Notification.Ephemeral,
103− id: mockModel.getNextId(),
104− summary: "Cole Raby",
105− body: "I did not expect it to be that late.",
106− icon: "../graphics/avatars/amanda.png",
107− secondaryIcon: "../graphics/applicationIcons/facebook.png",
108− actions: []
109− }
118+ mockModel.append(mockEphemeralNotification)
119+ }
110120
111− mockModel.append(n)
121+ Notification {
122+ id: mockEphemeralNonShapedIconNotification
123+ type: Notification.Ephemeral
124+ //nid: 4 //mockModel.getNextId()
125+ hints: {"x-canonical-non-shaped-icon": "true"}
126+ summary: "Contacts"
127+ body: "Synchronised contacts-database with cloud-storage."
128+ icon: "../graphics/applicationIcons/contacts-app.png"
129+ secondaryIcon: ""
130+ rawActions: [{ id: "reply_id", label: "Dummy"}]
112131 }
113132
114133 function addEphemeralNonShapedIconNotification() {
115− var n = {
116− type: Notification.Ephemeral,
117− id: mockModel.getNextId(),
118− hints: {"x-canonical-non-shaped-icon": "true"},
119− summary: "Contacts",
120− body: "Synchronised contacts-database with cloud-storage.",
121− icon: "../graphics/applicationIcons/contacts-app.png",
122− secondaryIcon: "",
123− actions: []
124− }
134+ mockModel.append(mockEphemeralNonShapedIconNotification)
135+ }
125136
126− mockModel.append(n)
137+ Notification {
138+ id: mockEphemeralIconSummaryNotification
139+ type: Notification.Ephemeral
140+ //nid: 5 //mockModel.getNextId()
141+ hints: {"x-canonical-non-shaped-icon": "false"}
142+ summary: "Photo upload completed"
143+ body: ""
144+ icon: "../graphics/applicationIcons/facebook.png"
145+ secondaryIcon: ""
146+ rawActions: [{ id: "reply_id", label: "Dummy"}]
127147 }
128148
129149 function addEphemeralIconSummaryNotification() {
130− var n = {
131− type: Notification.Ephemeral,
132− id: mockModel.getNextId(),
133− hints: {"x-canonical-non-shaped-icon": "false"},
134− summary: "Photo upload completed",
135− body: "",
136− icon: "../graphics/applicationIcons/facebook.png",
137− secondaryIcon: "",
138− actions: []
139− }
150+ mockModel.append(mockEphemeralIconSummaryNotification)
151+ }
140152
141− mockModel.append(n)
153+ Notification {
154+ id: mockInteractiveNotification
155+ type: Notification.Interactive
156+ //nid: 6 //mockModel.getNextId()
157+ summary: "Interactive notification"
158+ body: "This is a notification that can be clicked"
159+ icon: "../graphics/avatars/anna_olsson.png"
160+ secondaryIcon: ""
161+ rawActions: [{ id: "reply_id", label: "Dummy"}]
142162 }
143163
144164 function addInteractiveNotification() {
145− var n = {
146− type: Notification.Interactive,
147− id: mockModel.getNextId(),
148− summary: "Interactive notification",
149− body: "This is a notification that can be clicked",
150− icon: "../graphics/avatars/anna_olsson.png",
151− secondaryIcon: "",
152− actions: [{ id: "reply_id", label: "Dummy"}],
153− }
165+ mockModel.append(mockInteractiveNotification)
166+ }
154167
155− mockModel.append(n)
168+ Notification {
169+ id: mockConfirmationNotification
170+ type: Notification.Confirmation
171+ //nid: 7 //mockModel.getNextId()
172+ hints: {"x-canonical-non-shaped-icon": "true"}
173+ summary: "Confirmation notification"
174+ body: ""
175+ icon: "image://theme/audio-volume-medium"
176+ secondaryIcon: ""
177+ value: 50
178+ rawActions: [{ id: "reply_id", label: "Dummy"}]
156179 }
157180
158181 function addConfirmationNotification() {
159− var n = {
160− type: Notification.Confirmation,
161− id: mockModel.getNextId(),
162− hints: {"x-canonical-non-shaped-icon": "true"},
163− summary: "Confirmation notification",
164− body: "",
165− icon: "image://theme/audio-volume-medium",
166− secondaryIcon: "",
167− value: 50,
168− actions: [],
169− }
182+ mockModel.append(mockConfirmationNotification)
183+ }
170184
171− mockModel.append(n)
185+ Notification {
186+ id: mock2ndConfirmationNotification
187+ type: Notification.Confirmation
188+ //nid: 8 //mockModel.getNextId()
189+ hints: {"x-canonical-non-shaped-icon": "true",
190+ "x-canonical-value-bar-tint": "true"}
191+ summary: "Confirmation notification"
192+ body: "High Volume"
193+ icon: "image://theme/audio-volume-high"
194+ secondaryIcon: ""
195+ value: 85
196+ rawActions: [{ id: "reply_id", label: "Dummy"}]
172197 }
173198
174199 function add2ndConfirmationNotification() {
175− var n = {
176− type: Notification.Confirmation,
177− id: mockModel.getNextId(),
178− hints: {"x-canonical-non-shaped-icon": "true",
179− "x-canonical-value-bar-tint": "true"},
180− summary: "Confirmation notification",
181− body: "High Volume",
182− icon: "image://theme/audio-volume-high",
183− secondaryIcon: "",
184− value: 85,
185− actions: [],
186− }
187−
188− mockModel.append(n)
200+ mockModel.append(mock2ndConfirmationNotification)
189201 }
190202
191203 function clearNotifications() {