on xenial help sign in
Added qml-test for the new custom OptionToggle widget for snap-decision notifications. Adjusted existing qml-test for notifications accordingly.
545d96eMirco Müller
qml/Notifications/OptionToggle.qml+17
@@ -1,3 +1,19 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
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; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
1import QtQuick 2.0
17import QtQuick 2.0
2import Ubuntu.Components 0.1
18import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem
19import Ubuntu.Components.ListItems 0.1 as ListItem
@@ -45,6 +61,7 @@ UbuntuShape {
45 id: optionToggleEntry
61 id: optionToggleEntry
46
62
47 MouseArea {
63 MouseArea {
64+ objectName: "notify_button" + index
48 width: optionToggleContent.width
65 width: optionToggleContent.width
49 height: optionToggle.itemHeight
66 height: optionToggle.itemHeight
50
67
tests/qmltests/CMakeLists.txt+1
@@ -71,6 +71,7 @@ add_qml_test(Hud Result)
71add_qml_test(Launcher Launcher)
71add_qml_test(Launcher Launcher)
72add_qml_test(Notifications Notifications)
72add_qml_test(Notifications Notifications)
73add_qml_test(Notifications VisualSnapDecisionsQueue)
73add_qml_test(Notifications VisualSnapDecisionsQueue)
74+add_qml_test(Notifications OptionToggle)
74add_qml_test(Panel ActiveCallHint)
75add_qml_test(Panel ActiveCallHint)
75add_qml_test(Panel IndicatorRow)
76add_qml_test(Panel IndicatorRow)
76add_qml_test(Panel Indicators)
77add_qml_test(Panel Indicators)
tests/qmltests/Notifications/tst_Notifications.qml+3−72
@@ -61,24 +61,6 @@ Row {
61 }
61 }
62 }
62 }
63
63
64− function addSnapDecisionNotification() {
65− var n = {
66− type: Notification.SnapDecision,
67− hints: {"x-canonical-private-affirmative-tint": "true"},
68− summary: "Tom Ato",
69− body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
70− icon: "../graphics/avatars/funky.png",
71− secondaryIcon: "../graphics/applicationIcons/facebook.png",
72− actions: [{ id: "ok_id", label: "Ok"},
73− { id: "cancel_id", label: "Cancel"},
74− { id: "notreally_id", label: "Not really"},
75− { id: "noway_id", label: "messages:No way"},
76− { id: "nada_id", label: "messages:Nada"}]
77− }
78−
79− mockModel.append(n)
80− }
81−
82 function add2over1SnapDecisionNotification() {
64 function add2over1SnapDecisionNotification() {
83 var n = {
65 var n = {
84 type: Notification.SnapDecision,
66 type: Notification.SnapDecision,
@@ -191,12 +173,6 @@ Row {
191 anchors.fill: parent
173 anchors.fill: parent
192 anchors.margins: units.gu(1)
174 anchors.margins: units.gu(1)
193
175
194− Button {
195− width: parent.width
196− text: "add a snap-decision"
197− onClicked: addSnapDecisionNotification()
198− }
199−
200 Button {
176 Button {
201 width: parent.width
177 width: parent.width
202 text: "add a 2over1 snap-decision"
178 text: "add a 2over1 snap-decision"
@@ -248,29 +224,6 @@ Row {
248
224
249 function test_NotificationRenderer_data() {
225 function test_NotificationRenderer_data() {
250 return [
226 return [
251− {
252− tag: "Snap Decision with secondary icon and button-tint",
253− type: Notification.SnapDecision,
254− hints: {"x-canonical-private-affirmative-tint": "true"},
255− summary: "Tom Ato",
256− body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
257− icon: "../graphics/avatars/funky.png",
258− secondaryIcon: "../graphics/applicationIcons/facebook.png",
259− actions: [{ id: "ok_id", label: "Ok"},
260− { id: "cancel_id", label: "Cancel"},
261− { id: "notreally_id", label: "Not really"},
262− { id: "noway_id", label: "messages:No way"},
263− { id: "nada_id", label: "messages:Nada"}],
264− summaryVisible: true,
265− bodyVisible: true,
266− iconVisible: true,
267− shapedIcon: true,
268− nonShapedIcon: false,
269− secondaryIconVisible: true,
270− buttonRowVisible: true,
271− buttonTinted: true,
272− hasSound: false
273− },
274 {
227 {
275 tag: "2-over-1 Snap Decision with button-tint",
228 tag: "2-over-1 Snap Decision with button-tint",
276 type: Notification.SnapDecision,
229 type: Notification.SnapDecision,
@@ -498,31 +451,9 @@ Row {
498 actionSpy.clear()
451 actionSpy.clear()
499 waitForRendering(notification)
452 waitForRendering(notification)
500
453
501− // check if there's a ComboButton created due to more actions being passed
454+ // click one of the buttons
502− if (data.actions.length > 2) {
503− var comboButton = findChild(notification, "notify_button2")
504− tryCompareFunction(function() { return comboButton.expanded == false; }, true);
505−
506− // click to expand
507− tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == true; }, true);
508−
509− // try clicking on choices in expanded comboList
510− var choiceButton1 = findChild(notification, "notify_button3")
511− tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
512− compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
513− actionSpy.clear()
514−
515− var choiceButton2 = findChild(notification, "notify_button4")
516− tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
517− compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
518− actionSpy.clear()
519−
520− // click to collapse
521− //tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == false; }, true);
522− } else {
523− mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
455+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
524− compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
456+ compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
525− }
526 }
457 }
527 }
458 }
528 }
459 }
tests/qmltests/Notifications/tst_OptionToggle.qmlnew file+285
@@ -0,0 +1,285 @@
1+/*
2+ * Copyright (C) 2014 Canonical, Ltd.
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; version 3.
7+ *
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ */
16+
17+import QtQuick 2.0
18+import QtTest 1.0
19+import ".."
20+import "../../../qml/Notifications"
21+import Ubuntu.Components 0.1
22+import Unity.Test 0.1
23+import Unity.Notifications 1.0
24+import QtMultimedia 5.0
25+
26+Row {
27+ id: rootRow
28+
29+ Component {
30+ id: mockNotification
31+
32+ QtObject {
33+ function invokeAction(actionId) {
34+ mockModel.actionInvoked(actionId)
35+ }
36+ }
37+ }
38+
39+ ListModel {
40+ id: mockModel
41+
42+ signal actionInvoked(string actionId)
43+
44+ function getRaw(id) {
45+ return mockNotification.createObject(mockModel)
46+ }
47+
48+ // add the default/PlaceHolder notification to the model
49+ Component.onCompleted: {
50+ var n = {
51+ type: Notification.PlaceHolder,
52+ hints: {},
53+ summary: "",
54+ body: "",
55+ icon: "",
56+ secondaryIcon: "",
57+ actions: []
58+ }
59+
60+ append(n)
61+ }
62+ }
63+
64+ function addSnapDecisionNotification() {
65+ var n = {
66+ type: Notification.SnapDecision,
67+ hints: {"x-canonical-private-affirmative-tint": "true"},
68+ summary: "Incoming call",
69+ body: "Frank Zappa\n+44 (0)7736 027340",
70+ icon: "../graphics/avatars/funky.png",
71+ secondaryIcon: "image://theme/incoming-call",
72+ actions: [{ id: "ok_id", label: "Ok"},
73+ { id: "cancel_id", label: "Cancel"},
74+ { id: "dummy_id", label: "Quick reply"},
75+ { id: "late_id", label: "messages:I'm running late. I'm on my way."},
76+ { id: "later_id", label: "messages:I'm busy at the moment. I'll call later."}]
77+ }
78+
79+ mockModel.append(n)
80+ }
81+
82+ function clearNotifications() {
83+ mockModel.clear()
84+ }
85+
86+ function remove1stNotification() {
87+ if (mockModel.count > 0)
88+ mockModel.remove(0)
89+ }
90+
91+ Rectangle {
92+ id: notificationsRect
93+
94+ width: units.gu(40)
95+ height: units.gu(81)
96+ color: "#cccccc"
97+
98+ MouseArea{
99+ id: clickThroughCatcher
100+
101+ anchors.fill: parent
102+ }
103+
104+ Notifications {
105+ id: notifications
106+
107+ margin: units.gu(1)
108+
109+ anchors.fill: parent
110+ model: mockModel
111+ }
112+ }
113+
114+ Rectangle {
115+ id: interactiveControls
116+
117+ width: units.gu(30)
118+ height: units.gu(81)
119+ color: "grey"
120+
121+ Column {
122+ spacing: units.gu(1)
123+ anchors.fill: parent
124+ anchors.margins: units.gu(1)
125+
126+ Button {
127+ width: parent.width
128+ text: "add a snap-decision"
129+ onClicked: addSnapDecisionNotification()
130+ }
131+
132+ Button {
133+ width: parent.width
134+ text: "remove 1st notification"
135+ onClicked: remove1stNotification()
136+ }
137+
138+ Button {
139+ width: parent.width
140+ text: "clear model"
141+ onClicked: clearNotifications()
142+ }
143+ }
144+ }
145+
146+ UnityTestCase {
147+ id: root
148+ name: "NotificationRendererTest"
149+ when: windowShown
150+
151+ function test_NotificationRenderer_data() {
152+ return [
153+ {
154+ tag: "Snap Decision with secondary icon, button-tint and OptionToggle",
155+ type: Notification.SnapDecision,
156+ hints: {"x-canonical-private-affirmative-tint": "true"},
157+ summary: "Incoming call",
158+ body: "Frank Zappa\n+44 (0)7736 027340",
159+ icon: "../graphics/avatars/funky.png",
160+ secondaryIcon: "image://theme/incoming-call",
161+ actions: [{ id: "ok_id", label: "Ok"},
162+ { id: "cancel_id", label: "Cancel"},
163+ { id: "dummy_id", label: "Quick reply"},
164+ { id: "late_id", label: "messages:I'm running late. I'm on my way."},
165+ { id: "later_id", label: "messages:I'm busy at the moment. I'll call later."}],
166+ summaryVisible: true,
167+ bodyVisible: true,
168+ iconVisible: true,
169+ shapedIcon: true,
170+ nonShapedIcon: false,
171+ secondaryIconVisible: true,
172+ buttonRowVisible: true,
173+ buttonTinted: true,
174+ hasSound: false
175+ }
176+ ]
177+ }
178+
179+ SignalSpy {
180+ id: clickThroughSpy
181+
182+ target: clickThroughCatcher
183+ signalName: "clicked"
184+ }
185+
186+ SignalSpy {
187+ id: actionSpy
188+
189+ target: mockModel
190+ signalName: "actionInvoked"
191+ }
192+
193+ function cleanup() {
194+ clickThroughSpy.clear()
195+ actionSpy.clear()
196+ }
197+
198+ function test_NotificationRenderer(data) {
199+ // populate model with some mock notifications
200+ mockModel.append(data)
201+
202+ // make sure the view is properly updated before going on
203+ notifications.forceLayout();
204+ waitForRendering(notifications);
205+
206+ var notification = findChild(notifications, "notification" + (mockModel.count - 1))
207+ verify(notification !== undefined, "notification wasn't found");
208+
209+ waitForRendering(notification);
210+
211+ var icon = findChild(notification, "icon")
212+ var shapedIcon = findChild(notification, "shapedIcon")
213+ var nonShapedIcon = findChild(notification, "nonShapedIcon")
214+ var interactiveArea = findChild(notification, "interactiveArea")
215+ var secondaryIcon = findChild(notification, "secondaryIcon")
216+ var summaryLabel = findChild(notification, "summaryLabel")
217+ var bodyLabel = findChild(notification, "bodyLabel")
218+ var buttonRow = findChild(notification, "buttonRow")
219+
220+ compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
221+ compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect")
222+ compare(nonShapedIcon.visible, data.nonShapedIcon, "non-shaped-icon visibility is incorrect")
223+
224+ // test input does not fall through
225+ mouseClick(notification, notification.width / 2, notification.height / 2)
226+ if(data.type == Notification.Interactive) {
227+ actionSpy.wait()
228+ compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
229+ }
230+ compare(clickThroughSpy.count, 0, "click on notification fell through")
231+
232+ compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
233+ compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect")
234+ compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect")
235+ compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect")
236+
237+ var audioItem = findInvisibleChild(notification, "sound")
238+ compare(audioItem.playbackState, data.hasSound ? Audio.PlayingState : Audio.StoppedState, "Audio has wrong state")
239+
240+ if(data.buttonRowVisible) {
241+ var buttonCancel = findChild(buttonRow, "notify_button1")
242+ var buttonAccept = findChild(buttonRow, "notify_button0")
243+
244+ // only test the left/cancel-button if two actions have been passed in
245+ if (data.actions.length == 2) {
246+ tryCompareFunction(function() { mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2); return actionSpy.signalArguments.length > 0; }, true);
247+ compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
248+ actionSpy.clear()
249+ }
250+
251+ // check the tinting of the positive/right button
252+ verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
253+
254+ // click the positive/right button
255+ tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
256+ compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
257+ actionSpy.clear()
258+ waitForRendering(notification)
259+
260+ // check if there's a OptionToggle created due to more actions being passed
261+ if (data.actions.length > 2) {
262+ var optionToggle = findChild(notification, "notify_button2")
263+ tryCompareFunction(function() { return optionToggle.expanded == false; }, true);
264+
265+ // click to expand
266+ tryCompareFunction(function() { mouseClick(optionToggle, optionToggle.width / 2, optionToggle.height / 2); return optionToggle.expanded == true; }, true);
267+
268+ // try clicking on choices in expanded comboList
269+ var choiceButton1 = findChild(notification, "notify_button3")
270+ tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
271+ compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
272+ actionSpy.clear()
273+
274+ var choiceButton2 = findChild(notification, "notify_button4")
275+ tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
276+ compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
277+ actionSpy.clear()
278+ } else {
279+ mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
280+ compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
281+ }
282+ }
283+ }
284+ }
285+}