~mterry/+junk/u8.2

« back to all changes in this revision

Viewing changes to tests/qmltests/Notifications/tst_Notifications.qml

  • Committer: Michael Terry
  • Date: 2014-11-17 14:56:04 UTC
  • mfrom: (1317.1.118 unity8)
  • Revision ID: michael.terry@canonical.com-20141117145604-96dn9p5nwkifq2f4
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
import Unity.Notifications 1.0
24
24
import QtMultimedia 5.0
25
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: {
 
26
Item {
 
27
    width: notificationsRect.width + interactiveControls.width
 
28
    height: notificationsRect.height
 
29
 
 
30
    Row {
 
31
        id: rootRow
 
32
 
 
33
        Component {
 
34
            id: mockNotification
 
35
 
 
36
            QtObject {
 
37
                function invokeAction(actionId) {
 
38
                    mockModel.actionInvoked(actionId)
 
39
                }
 
40
            }
 
41
        }
 
42
 
 
43
        ListModel {
 
44
            id: mockModel
 
45
            dynamicRoles: true
 
46
 
 
47
            signal actionInvoked(string actionId)
 
48
 
 
49
            function getRaw(id) {
 
50
                return mockNotification.createObject(mockModel)
 
51
            }
 
52
 
 
53
            // add the default/PlaceHolder notification to the model
 
54
            Component.onCompleted: {
 
55
                var n = {
 
56
                    type: Notification.PlaceHolder,
 
57
                    hints: {},
 
58
                    summary: "",
 
59
                    body: "",
 
60
                    icon: "",
 
61
                    secondaryIcon: "",
 
62
                    actions: []
 
63
                }
 
64
 
 
65
                append(n)
 
66
            }
 
67
        }
 
68
 
 
69
        function add2over1SnapDecisionNotification() {
50
70
            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: "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() {
83
 
        var n = {
84
 
            type: Notification.SnapDecision,
85
 
            hints: {"x-canonical-private-affirmative-tint": "true",},
86
 
            summary: "Theatre at Ferria Stadium",
87
 
            body: "at Ferria Stadium in Bilbao, Spain\n07578545317",
88
 
            icon: "",
89
 
            secondaryIcon: "",
90
 
            actions: [{ id: "ok_id", label: "Ok"},
91
 
                      { id: "snooze_id", label: "Snooze"},
92
 
                      { id: "view_id", label: "View"}]
93
 
        }
94
 
 
95
 
        mockModel.append(n)
96
 
    }
97
 
 
98
 
    function addEphemeralNotification() {
99
 
        var n = {
100
 
            type: Notification.Ephemeral,
101
 
            summary: "Cole Raby",
102
 
            body: "I did not expect it to be that late.",
103
 
            icon: "../graphics/avatars/amanda.png",
104
 
            secondaryIcon: "../graphics/applicationIcons/facebook.png",
105
 
            actions: []
106
 
        }
107
 
 
108
 
        mockModel.append(n)
109
 
    }
110
 
 
111
 
    function addEphemeralNonShapedIconNotification() {
112
 
        var n = {
113
 
            type: Notification.Ephemeral,
114
 
            hints: {"x-canonical-non-shaped-icon": "true"},
115
 
            summary: "Contacts",
116
 
            body: "Synchronised contacts-database with cloud-storage.",
117
 
            icon: "../graphics/applicationIcons/contacts-app.png",
118
 
            secondaryIcon: "",
119
 
            actions: []
120
 
        }
121
 
 
122
 
        mockModel.append(n)
123
 
    }
124
 
 
125
 
    function addEphemeralIconSummaryNotification() {
126
 
        var n = {
127
 
            type: Notification.Ephemeral,
128
 
            summary: "Photo upload completed",
129
 
            body: "",
130
 
            icon: "",
131
 
            secondaryIcon: "../graphics/applicationIcons/facebook.png",
132
 
            actions: []
133
 
        }
134
 
 
135
 
        mockModel.append(n)
136
 
    }
137
 
 
138
 
    function addInteractiveNotification() {
139
 
        var n = {
140
 
            type: Notification.Interactive,
141
 
            summary: "Interactive notification",
142
 
            body: "This is a notification that can be clicked",
143
 
            icon: "../graphics/avatars/anna_olsson.png",
144
 
            secondaryIcon: "",
145
 
            actions: [{ id: "reply_id", label: "Dummy"}],
146
 
        }
147
 
 
148
 
        mockModel.append(n)
149
 
    }
150
 
 
151
 
    function clearNotifications() {
152
 
        mockModel.clear()
153
 
    }
154
 
 
155
 
    function remove1stNotification() {
156
 
        if (mockModel.count > 0)
157
 
            mockModel.remove(0)
158
 
    }
159
 
 
160
 
    Rectangle {
161
 
        id: notificationsRect
162
 
 
163
 
        width: units.gu(40)
164
 
        height: units.gu(71)
165
 
 
166
 
        MouseArea{
167
 
            id: clickThroughCatcher
168
 
 
169
 
            anchors.fill: parent
170
 
        }
171
 
 
172
 
        Notifications {
173
 
            id: notifications
174
 
 
175
 
            margin: units.gu(1)
176
 
 
177
 
            anchors.fill: parent
178
 
            model: mockModel
179
 
        }
180
 
    }
181
 
 
182
 
    Rectangle {
183
 
        id: interactiveControls
184
 
 
185
 
        width: units.gu(30)
186
 
        height: units.gu(81)
187
 
        color: "grey"
188
 
 
189
 
        Column {
190
 
            spacing: units.gu(1)
191
 
            anchors.fill: parent
192
 
            anchors.margins: units.gu(1)
193
 
 
194
 
            Button {
195
 
                width: parent.width
196
 
                text: "add a snap-decision"
197
 
                onClicked: addSnapDecisionNotification()
198
 
            }
199
 
 
200
 
            Button {
201
 
                width: parent.width
202
 
                text: "add a 2over1 snap-decision"
203
 
                onClicked: add2over1SnapDecisionNotification()
204
 
            }
205
 
 
206
 
            Button {
207
 
                width: parent.width
208
 
                text: "add an ephemeral"
209
 
                onClicked: addEphemeralNotification()
210
 
            }
211
 
 
212
 
            Button {
213
 
                width: parent.width
214
 
                text: "add an non-shaped-icon-summary-body"
215
 
                onClicked: addEphemeralNonShapedIconNotification()
216
 
            }
217
 
 
218
 
            Button {
219
 
                width: parent.width
220
 
                text: "add an icon-summary"
221
 
                onClicked: addEphemeralIconSummaryNotification()
222
 
            }
223
 
 
224
 
            Button {
225
 
                width: parent.width
226
 
                text: "add an interactive"
227
 
                onClicked: addInteractiveNotification()
228
 
            }
229
 
 
230
 
            Button {
231
 
                width: parent.width
232
 
                text: "remove 1st notification"
233
 
                onClicked: remove1stNotification()
234
 
            }
235
 
 
236
 
            Button {
237
 
                width: parent.width
238
 
                text: "clear model"
239
 
                onClicked: clearNotifications()
240
 
            }
241
 
        }
242
 
    }
243
 
 
244
 
    UnityTestCase {
245
 
        id: root
246
 
        name: "NotificationRendererTest"
247
 
        when: windowShown
248
 
 
249
 
        function test_NotificationRenderer_data() {
250
 
            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
 
            {
275
 
                tag: "2-over-1 Snap Decision with button-tint",
276
71
                type: Notification.SnapDecision,
277
72
                hints: {"x-canonical-private-affirmative-tint": "true"},
278
73
                summary: "Theatre at Ferria Stadium",
281
76
                secondaryIcon: "",
282
77
                actions: [{ id: "ok_id", label: "Ok"},
283
78
                          { id: "snooze_id", label: "Snooze"},
284
 
                          { id: "view_id", label: "View"}],
285
 
                summaryVisible: true,
286
 
                bodyVisible: true,
287
 
                iconVisible: false,
288
 
                shapedIcon: false,
289
 
                nonShapedIcon: false,
290
 
                secondaryIconVisible: false,
291
 
                buttonRowVisible: false,
292
 
                buttonTinted: true,
293
 
                hasSound: false
294
 
            },
295
 
            {
296
 
                tag: "Ephemeral notification - icon-summary layout",
297
 
                type: Notification.Ephemeral,
298
 
                hints: {"x-canonical-private-affirmative-tint": "false"},
 
79
                          { id: "view_id", label: "View"}]
 
80
            }
 
81
 
 
82
            mockModel.append(n)
 
83
        }
 
84
 
 
85
        function addEphemeralNotification() {
 
86
            var n = {
 
87
                type: Notification.Ephemeral,
 
88
                summary: "Cole Raby",
 
89
                body: "I did not expect it to be that late.",
 
90
                icon: "../graphics/avatars/amanda.png",
 
91
                secondaryIcon: "../graphics/applicationIcons/facebook.png",
 
92
                actions: []
 
93
            }
 
94
 
 
95
            mockModel.append(n)
 
96
        }
 
97
 
 
98
        function addEphemeralNonShapedIconNotification() {
 
99
            var n = {
 
100
                type: Notification.Ephemeral,
 
101
                hints: {"x-canonical-non-shaped-icon": "true"},
 
102
                summary: "Contacts",
 
103
                body: "Synchronised contacts-database with cloud-storage.",
 
104
                icon: "../graphics/applicationIcons/contacts-app.png",
 
105
                secondaryIcon: "",
 
106
                actions: []
 
107
            }
 
108
 
 
109
            mockModel.append(n)
 
110
        }
 
111
 
 
112
        function addEphemeralIconSummaryNotification() {
 
113
            var n = {
 
114
                type: Notification.Ephemeral,
 
115
                hints: {"x-canonical-non-shaped-icon": "false"},
299
116
                summary: "Photo upload completed",
300
117
                body: "",
301
 
                icon: "",
302
 
                secondaryIcon: "../graphics/applicationIcons/facebook.png",
303
 
                actions: [],
304
 
                summaryVisible: true,
305
 
                bodyVisible: false,
306
 
                iconVisible: false,
307
 
                shapedIcon: false,
308
 
                nonShapedIcon: false,
309
 
                secondaryIconVisible: true,
310
 
                buttonRowVisible: false,
311
 
                buttonTinted: false,
312
 
                hasSound: false
313
 
            },
314
 
            {
315
 
                tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
316
 
                type: Notification.Ephemeral,
317
 
                hints: {"x-canonical-private-affirmative-tint": "false",
318
 
                        "sound-file": "dummy.ogg",
319
 
                        "suppress-sound": "true"},
320
 
                summary: "New comment successfully published",
321
 
                body: "",
322
 
                icon: "",
323
 
                secondaryIcon: "../graphics/applicationIcons/facebook.png",
324
 
                actions: [],
325
 
                summaryVisible: true,
326
 
                bodyVisible: false,
327
 
                interactiveAreaEnabled: false,
328
 
                iconVisible: false,
329
 
                shapedIcon: false,
330
 
                nonShapedIcon: false,
331
 
                secondaryIconVisible: true,
332
 
                buttonRowVisible: false,
333
 
                buttonTinted: false,
334
 
                hasSound: false
335
 
            },
336
 
            {
337
 
                tag: "Interactive notification",
 
118
                icon: "../graphics/applicationIcons/facebook.png",
 
119
                secondaryIcon: "",
 
120
                actions: []
 
121
            }
 
122
 
 
123
            mockModel.append(n)
 
124
        }
 
125
 
 
126
        function addInteractiveNotification() {
 
127
            var n = {
338
128
                type: Notification.Interactive,
339
 
                hints: {"x-canonical-private-affirmative-tint": "false",
340
 
                        "sound-file": "dummy.ogg"},
341
129
                summary: "Interactive notification",
342
130
                body: "This is a notification that can be clicked",
343
 
                icon: "../graphics/avatars/amanda.png",
 
131
                icon: "../graphics/avatars/anna_olsson.png",
344
132
                secondaryIcon: "",
345
133
                actions: [{ id: "reply_id", label: "Dummy"}],
346
 
                summaryVisible: true,
347
 
                bodyVisible: true,
348
 
                iconVisible: true,
349
 
                shapedIcon: true,
350
 
                nonShapedIcon: false,
351
 
                secondaryIconVisible: false,
352
 
                buttonRowVisible: false,
353
 
                buttonTinted: false,
354
 
                hasSound: true
355
 
            },
356
 
            {
357
 
                tag: "Snap Decision without secondary icon and no button-tint",
358
 
                type: Notification.SnapDecision,
359
 
                hints: {"x-canonical-private-affirmative-tint": "false",
360
 
                        "sound-file": "dummy.ogg"},
361
 
                summary: "Bro Coly",
362
 
                body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
363
 
                icon: "../graphics/avatars/anna_olsson.png",
364
 
                secondaryIcon: "",
365
 
                actions: [{ id: "accept_id", label: "Accept"},
366
 
                          { id: "reject_id", label: "Reject"}],
367
 
                summaryVisible: true,
368
 
                bodyVisible: true,
369
 
                iconVisible: true,
370
 
                shapedIcon: true,
371
 
                nonShapedIcon: false,
372
 
                secondaryIconVisible: false,
373
 
                buttonRowVisible: true,
374
 
                buttonTinted: false,
375
 
                hasSound: true
376
 
            },
377
 
            {
378
 
                tag: "Ephemeral notification",
379
 
                type: Notification.Ephemeral,
380
 
                hints: {"x-canonical-private-affirmative-tint": "false",
381
 
                        "sound-file": "dummy.ogg"},
382
 
                summary: "Cole Raby",
383
 
                body: "I did not expect it to be that late.",
384
 
                icon: "../graphics/avatars/funky.png",
385
 
                secondaryIcon: "../graphics/applicationIcons/facebook.png",
386
 
                actions: [],
387
 
                summaryVisible: true,
388
 
                bodyVisible: true,
389
 
                iconVisible: true,
390
 
                shapedIcon: true,
391
 
                nonShapedIcon: false,
392
 
                secondaryIconVisible: true,
393
 
                buttonRowVisible: false,
394
 
                buttonTinted: false,
395
 
                hasSound: true
396
 
            },
397
 
            {
398
 
                tag: "Ephemeral notification with non-shaped icon",
399
 
                type: Notification.Ephemeral,
400
 
                hints: {"x-canonical-private-affirmative-tint": "false",
401
 
                        "x-canonical-non-shaped-icon": "true"},
402
 
                summary: "Contacts",
403
 
                body: "Synchronised contacts-database with cloud-storage.",
404
 
                icon: "../graphics/applicationIcons/contacts-app.png",
405
 
                secondaryIcon: "",
406
 
                actions: [],
407
 
                summaryVisible: true,
408
 
                bodyVisible: true,
409
 
                iconVisible: true,
410
 
                shapedIcon: false,
411
 
                nonShapedIcon: true,
412
 
                secondaryIconVisible: false,
413
 
                buttonRowVisible: false,
414
 
                buttonTinted: false,
415
 
                hasSound: false
416
 
            }
417
 
            ]
418
 
        }
419
 
 
420
 
        SignalSpy {
421
 
            id: clickThroughSpy
422
 
 
423
 
            target: clickThroughCatcher
424
 
            signalName: "clicked"
425
 
        }
426
 
 
427
 
        SignalSpy {
428
 
            id: actionSpy
429
 
 
430
 
            target: mockModel
431
 
            signalName: "actionInvoked"
432
 
        }
433
 
 
434
 
        function cleanup() {
435
 
            clickThroughSpy.clear()
436
 
            actionSpy.clear()
437
 
        }
438
 
 
439
 
        function test_NotificationRenderer(data) {
440
 
            // populate model with some mock notifications
441
 
            mockModel.append(data)
442
 
 
443
 
            // make sure the view is properly updated before going on
444
 
            notifications.forceLayout();
445
 
            waitForRendering(notifications);
446
 
 
447
 
            var notification = findChild(notifications, "notification" + (mockModel.count - 1))
448
 
            verify(notification !== undefined, "notification wasn't found");
449
 
 
450
 
            waitForRendering(notification);
451
 
 
452
 
            var icon = findChild(notification, "icon")
453
 
            var shapedIcon = findChild(notification, "shapedIcon")
454
 
            var nonShapedIcon = findChild(notification, "nonShapedIcon")
455
 
            var interactiveArea = findChild(notification, "interactiveArea")
456
 
            var secondaryIcon = findChild(notification, "secondaryIcon")
457
 
            var summaryLabel = findChild(notification, "summaryLabel")
458
 
            var bodyLabel = findChild(notification, "bodyLabel")
459
 
            var buttonRow = findChild(notification, "buttonRow")
460
 
 
461
 
            compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
462
 
            compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect")
463
 
            compare(nonShapedIcon.visible, data.nonShapedIcon, "non-shaped-icon visibility is incorrect")
464
 
 
465
 
            // test input does not fall through
466
 
            mouseClick(notification, notification.width / 2, notification.height / 2)
467
 
            if(data.type == Notification.Interactive) {
468
 
                actionSpy.wait()
469
 
                compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
470
 
            }
471
 
            compare(clickThroughSpy.count, 0, "click on notification fell through")
472
 
 
473
 
            compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
474
 
            compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect")
475
 
            compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect")
476
 
            compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect")
477
 
 
478
 
            var audioItem = findInvisibleChild(notification, "sound")
479
 
            compare(audioItem.playbackState, data.hasSound ? Audio.PlayingState : Audio.StoppedState, "Audio has wrong state")
480
 
 
481
 
            if(data.buttonRowVisible) {
482
 
                var buttonCancel = findChild(buttonRow, "notify_button1")
483
 
                var buttonAccept = findChild(buttonRow, "notify_button0")
484
 
 
485
 
                // only test the left/cancel-button if two actions have been passed in
486
 
                if (data.actions.length == 2) {
487
 
                    tryCompareFunction(function() { mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2); return actionSpy.signalArguments.length > 0; }, true);
488
 
                    compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
489
 
                    actionSpy.clear()
490
 
                }
491
 
 
492
 
                // check the tinting of the positive/right button
493
 
                verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
494
 
 
495
 
                // click the positive/right button
496
 
                tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
497
 
                compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
 
134
            }
 
135
 
 
136
            mockModel.append(n)
 
137
        }
 
138
 
 
139
        function addConfirmationNotification() {
 
140
            var n = {
 
141
                type: Notification.Confirmation,
 
142
                hints: {"x-canonical-non-shaped-icon": "true"},
 
143
                summary: "Confirmation notification",
 
144
                body: "",
 
145
                icon: "image://theme/audio-volume-medium",
 
146
                secondaryIcon: "",
 
147
                value: 50,
 
148
                actions: [],
 
149
            }
 
150
 
 
151
            mockModel.append(n)
 
152
        }
 
153
 
 
154
        function add2ndConfirmationNotification() {
 
155
            var n = {
 
156
                type: Notification.Confirmation,
 
157
                hints: {"x-canonical-non-shaped-icon": "true",
 
158
                        "x-canonical-value-bar-tint": "true"},
 
159
                summary: "Confirmation notification",
 
160
                body: "High Volume",
 
161
                icon: "image://theme/audio-volume-high",
 
162
                secondaryIcon: "",
 
163
                value: 85,
 
164
                actions: [],
 
165
            }
 
166
 
 
167
            mockModel.append(n)
 
168
        }
 
169
 
 
170
        function clearNotifications() {
 
171
            while(mockModel.count > 1) {
 
172
                remove1stNotification()
 
173
            }
 
174
        }
 
175
 
 
176
        function remove1stNotification() {
 
177
            if (mockModel.count > 1)
 
178
                mockModel.remove(1)
 
179
        }
 
180
 
 
181
        Rectangle {
 
182
            id: notificationsRect
 
183
 
 
184
            width: units.gu(40)
 
185
            height: units.gu(115)
 
186
 
 
187
            MouseArea{
 
188
                id: clickThroughCatcher
 
189
 
 
190
                anchors.fill: parent
 
191
            }
 
192
 
 
193
            Notifications {
 
194
                id: notifications
 
195
 
 
196
                margin: units.gu(1)
 
197
 
 
198
                anchors.fill: parent
 
199
                model: mockModel
 
200
            }
 
201
        }
 
202
 
 
203
        Rectangle {
 
204
            id: interactiveControls
 
205
 
 
206
            width: units.gu(30)
 
207
            height: units.gu(115)
 
208
            color: "grey"
 
209
 
 
210
            Column {
 
211
                spacing: units.gu(1)
 
212
                anchors.fill: parent
 
213
                anchors.margins: units.gu(1)
 
214
 
 
215
                Button {
 
216
                    width: parent.width
 
217
                    text: "add a 2over1 snap-decision"
 
218
                    onClicked: rootRow.add2over1SnapDecisionNotification()
 
219
                }
 
220
 
 
221
                Button {
 
222
                    width: parent.width
 
223
                    text: "add an ephemeral"
 
224
                    onClicked: rootRow.addEphemeralNotification()
 
225
                }
 
226
 
 
227
                Button {
 
228
                    width: parent.width
 
229
                    text: "add an non-shaped-icon-summary-body"
 
230
                    onClicked: rootRow.addEphemeralNonShapedIconNotification()
 
231
                }
 
232
 
 
233
                Button {
 
234
                    width: parent.width
 
235
                    text: "add an icon-summary"
 
236
                    onClicked: rootRow.addEphemeralIconSummaryNotification()
 
237
                }
 
238
 
 
239
                Button {
 
240
                    width: parent.width
 
241
                    text: "add an interactive"
 
242
                    onClicked: rootRow.addInteractiveNotification()
 
243
                }
 
244
 
 
245
                Button {
 
246
                    width: parent.width
 
247
                    text: "add a confirmation"
 
248
                    onClicked: rootRow.addConfirmationNotification()
 
249
                }
 
250
 
 
251
                Button {
 
252
                    width: parent.width
 
253
                    text: "add a 2nd confirmation"
 
254
                    onClicked: rootRow.add2ndConfirmationNotification()
 
255
                }
 
256
 
 
257
                Button {
 
258
                    width: parent.width
 
259
                    text: "remove 1st notification"
 
260
                    onClicked: rootRow.remove1stNotification()
 
261
                }
 
262
 
 
263
                Button {
 
264
                    width: parent.width
 
265
                    text: "clear model"
 
266
                    onClicked: rootRow.clearNotifications()
 
267
                }
 
268
            }
 
269
        }
 
270
 
 
271
        UnityTestCase {
 
272
            id: root
 
273
            name: "NotificationRendererTest"
 
274
            when: windowShown
 
275
 
 
276
            function test_NotificationRenderer_data() {
 
277
                return [
 
278
                {
 
279
                    tag: "2-over-1 Snap Decision with button-tint",
 
280
                    type: Notification.SnapDecision,
 
281
                    hints: {"x-canonical-private-affirmative-tint": "true"},
 
282
                    summary: "Theatre at Ferria Stadium",
 
283
                    body: "at Ferria Stadium in Bilbao, Spain\n07578545317",
 
284
                    icon: "",
 
285
                    secondaryIcon: "",
 
286
                    actions: [{ id: "ok_id", label: "Ok"},
 
287
                              { id: "snooze_id", label: "Snooze"},
 
288
                              { id: "view_id", label: "View"}],
 
289
                    summaryVisible: true,
 
290
                    bodyVisible: true,
 
291
                    iconVisible: false,
 
292
                    centeredIconVisible: false,
 
293
                    shaped: false,
 
294
                    secondaryIconVisible: false,
 
295
                    buttonRowVisible: false,
 
296
                    buttonTinted: true,
 
297
                    hasSound: false,
 
298
                    valueVisible: false,
 
299
                    valueLabelVisible: false,
 
300
                    valueTinted: false
 
301
                },
 
302
                {
 
303
                    tag: "Ephemeral notification - icon-summary layout",
 
304
                    type: Notification.Ephemeral,
 
305
                    hints: {},
 
306
                    summary: "Photo upload completed",
 
307
                    body: "",
 
308
                    icon: "../graphics/applicationIcons/facebook.png",
 
309
                    secondaryIcon: "",
 
310
                    actions: [],
 
311
                    summaryVisible: true,
 
312
                    bodyVisible: false,
 
313
                    iconVisible: true,
 
314
                    centeredIconVisible: false,
 
315
                    shaped: true,
 
316
                    secondaryIconVisible: false,
 
317
                    buttonRowVisible: false,
 
318
                    buttonTinted: false,
 
319
                    hasSound: false,
 
320
                    valueVisible: false,
 
321
                    valueLabelVisible: false,
 
322
                    valueTinted: false
 
323
                },
 
324
                {
 
325
                    tag: "Ephemeral notification - check suppression of secondary icon for icon-summary layout",
 
326
                    type: Notification.Ephemeral,
 
327
                    hints: {"x-canonical-private-affirmative-tint": "false",
 
328
                            "sound-file": "dummy.ogg",
 
329
                            "suppress-sound": "true"},
 
330
                    summary: "New comment successfully published",
 
331
                    body: "",
 
332
                    icon: "",
 
333
                    secondaryIcon: "../graphics/applicationIcons/facebook.png",
 
334
                    actions: [],
 
335
                    summaryVisible: true,
 
336
                    bodyVisible: false,
 
337
                    interactiveAreaEnabled: false,
 
338
                    iconVisible: false,
 
339
                    centeredIconVisible: false,
 
340
                    shaped: false,
 
341
                    secondaryIconVisible: true,
 
342
                    buttonRowVisible: false,
 
343
                    buttonTinted: false,
 
344
                    hasSound: false,
 
345
                    valueVisible: false,
 
346
                    valueLabelVisible: false,
 
347
                    valueTinted: false
 
348
                },
 
349
                {
 
350
                    tag: "Interactive notification",
 
351
                    type: Notification.Interactive,
 
352
                    hints: {"x-canonical-private-affirmative-tint": "false",
 
353
                            "sound-file": "dummy.ogg"},
 
354
                    summary: "Interactive notification",
 
355
                    body: "This is a notification that can be clicked",
 
356
                    icon: "../graphics/avatars/amanda.png",
 
357
                    secondaryIcon: "",
 
358
                    actions: [{ id: "reply_id", label: "Dummy"}],
 
359
                    summaryVisible: true,
 
360
                    bodyVisible: true,
 
361
                    iconVisible: true,
 
362
                    centeredIconVisible: false,
 
363
                    shaped: true,
 
364
                    secondaryIconVisible: false,
 
365
                    buttonRowVisible: false,
 
366
                    buttonTinted: false,
 
367
                    hasSound: true,
 
368
                    valueVisible: false,
 
369
                    valueLabelVisible: false,
 
370
                    valueTinted: false
 
371
                },
 
372
                {
 
373
                    tag: "Snap Decision without secondary icon and no button-tint",
 
374
                    type: Notification.SnapDecision,
 
375
                    hints: {"x-canonical-private-affirmative-tint": "false",
 
376
                            "sound-file": "dummy.ogg"},
 
377
                    summary: "Bro Coly",
 
378
                    body: "At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.",
 
379
                    icon: "../graphics/avatars/anna_olsson.png",
 
380
                    secondaryIcon: "",
 
381
                    actions: [{ id: "accept_id", label: "Accept"},
 
382
                              { id: "reject_id", label: "Reject"}],
 
383
                    summaryVisible: true,
 
384
                    bodyVisible: true,
 
385
                    iconVisible: true,
 
386
                    centeredIconVisible: false,
 
387
                    shaped: true,
 
388
                    secondaryIconVisible: false,
 
389
                    buttonRowVisible: true,
 
390
                    buttonTinted: false,
 
391
                    hasSound: true,
 
392
                    valueVisible: false,
 
393
                    valueLabelVisible: false,
 
394
                    valueTinted: false
 
395
                },
 
396
                {
 
397
                    tag: "Ephemeral notification",
 
398
                    type: Notification.Ephemeral,
 
399
                    hints: {"x-canonical-private-affirmative-tint": "false",
 
400
                            "sound-file": "dummy.ogg"},
 
401
                    summary: "Cole Raby",
 
402
                    body: "I did not expect it to be that late.",
 
403
                    icon: "../graphics/avatars/funky.png",
 
404
                    secondaryIcon: "../graphics/applicationIcons/facebook.png",
 
405
                    actions: [],
 
406
                    summaryVisible: true,
 
407
                    bodyVisible: true,
 
408
                    iconVisible: true,
 
409
                    centeredIconVisible: false,
 
410
                    shaped: true,
 
411
                    secondaryIconVisible: true,
 
412
                    buttonRowVisible: false,
 
413
                    buttonTinted: false,
 
414
                    hasSound: true,
 
415
                    valueVisible: false,
 
416
                    valueLabelVisible: false,
 
417
                    valueTinted: false
 
418
                },
 
419
                {
 
420
                    tag: "Ephemeral notification with non-shaped icon",
 
421
                    type: Notification.Ephemeral,
 
422
                    hints: {"x-canonical-private-affirmative-tint": "false",
 
423
                            "x-canonical-non-shaped-icon": "true"},
 
424
                    summary: "Contacts",
 
425
                    body: "Synchronised contacts-database with cloud-storage.",
 
426
                    icon: "image://theme/contacts-app",
 
427
                    secondaryIcon: "",
 
428
                    actions: [],
 
429
                    summaryVisible: true,
 
430
                    bodyVisible: true,
 
431
                    iconVisible: true,
 
432
                    centeredIconVisible: false,
 
433
                    shaped: false,
 
434
                    secondaryIconVisible: false,
 
435
                    buttonRowVisible: false,
 
436
                    buttonTinted: false,
 
437
                    hasSound: false,
 
438
                    valueVisible: false,
 
439
                    valueLabelVisible: false,
 
440
                    valueTinted: false
 
441
                },
 
442
                {
 
443
                    tag: "Confirmation notification with value",
 
444
                    type: Notification.Confirmation,
 
445
                    hints: {"x-canonical-non-shaped-icon": "true"},
 
446
                    summary: "",
 
447
                    body: "",
 
448
                    icon: "image://theme/audio-volume-medium",
 
449
                    secondaryIcon: "",
 
450
                    value: 50,
 
451
                    actions: [],
 
452
                    summaryVisible: false,
 
453
                    bodyVisible: false,
 
454
                    iconVisible: false,
 
455
                    centeredIconVisible: true,
 
456
                    shaped: false,
 
457
                    secondaryIconVisible: false,
 
458
                    buttonRowVisible: false,
 
459
                    buttonTinted: false,
 
460
                    hasSound: false,
 
461
                    valueVisible: true,
 
462
                    valueLabelVisible: false,
 
463
                    valueTinted: false
 
464
                },
 
465
                {
 
466
                    tag: "Confirmation notification with value, label and tint",
 
467
                    type: Notification.Confirmation,
 
468
                    hints: {"x-canonical-non-shaped-icon": "true",
 
469
                            "x-canonical-value-bar-tint" : "true"},
 
470
                    summary: "",
 
471
                    body: "High Volume",
 
472
                    icon: "image://theme/audio-volume-high",
 
473
                    secondaryIcon: "",
 
474
                    value: 85,
 
475
                    actions: [],
 
476
                    summaryVisible: false,
 
477
                    bodyVisible: false,
 
478
                    iconVisible: false,
 
479
                    centeredIconVisible: true,
 
480
                    shaped: false,
 
481
                    secondaryIconVisible: false,
 
482
                    buttonRowVisible: false,
 
483
                    buttonTinted: false,
 
484
                    hasSound: false,
 
485
                    valueVisible: true,
 
486
                    valueLabelVisible: true,
 
487
                    valueTinted: true
 
488
                }
 
489
                ]
 
490
            }
 
491
 
 
492
            SignalSpy {
 
493
                id: clickThroughSpy
 
494
 
 
495
                target: clickThroughCatcher
 
496
                signalName: "clicked"
 
497
            }
 
498
 
 
499
            SignalSpy {
 
500
                id: actionSpy
 
501
 
 
502
                target: mockModel
 
503
                signalName: "actionInvoked"
 
504
            }
 
505
 
 
506
            function cleanup() {
 
507
                clickThroughSpy.clear()
498
508
                actionSpy.clear()
499
 
                waitForRendering(notification)
500
 
 
501
 
                // check if there's a ComboButton created due to more actions being passed
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)
524
 
                    compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
 
509
            }
 
510
 
 
511
            function test_NotificationRenderer(data) {
 
512
                // populate model with some mock notifications
 
513
                mockModel.append(data)
 
514
 
 
515
                // make sure the view is properly updated before going on
 
516
                notifications.forceLayout();
 
517
                waitForRendering(notifications);
 
518
 
 
519
                var notification = findChild(notifications, "notification" + (mockModel.count - 1))
 
520
                verify(notification !== undefined, "notification wasn't found");
 
521
 
 
522
                waitForRendering(notification);
 
523
 
 
524
                var icon = findChild(notification, "icon")
 
525
                var centeredIcon = findChild(notification, "centeredIcon")
 
526
                var interactiveArea = findChild(notification, "interactiveArea")
 
527
                var secondaryIcon = findChild(notification, "secondaryIcon")
 
528
                var summaryLabel = findChild(notification, "summaryLabel")
 
529
                var bodyLabel = findChild(notification, "bodyLabel")
 
530
                var buttonRow = findChild(notification, "buttonRow")
 
531
                var valueIndicator = findChild(notification, "valueIndicator")
 
532
                var valueLabel = findChild(notification, "valueLabel")
 
533
                var innerBar = findChild(notification, "innerBar")
 
534
 
 
535
                compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect")
 
536
                if (icon.visible) {
 
537
                    compare(icon.shaped, data.shaped, "shaped-status is incorrect")
 
538
                }
 
539
                compare(centeredIcon.visible, data.centeredIconVisible, "centered-icon visibility is incorrect")
 
540
                if (centeredIcon.visible) {
 
541
                    compare(centeredIcon.shaped, data.shaped, "shaped-status is incorrect")
 
542
                }
 
543
                compare(valueIndicator.visible, data.valueVisible, "value-indicator visibility is incorrect")
 
544
                if (valueIndicator.visible) {
 
545
                    verify(innerBar.color === data.valueTinted ? UbuntuColors.orange : "white", "value-bar has the wrong color-tint")
 
546
                }
 
547
                compare(valueLabel.visible, data.valueLabelVisible, "value-label visibility is incorrect")
 
548
 
 
549
                // test input does not fall through
 
550
                mouseClick(notification, notification.width / 2, notification.height / 2)
 
551
                if(data.type == Notification.Interactive) {
 
552
                    actionSpy.wait()
 
553
                    compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id for interactive action")
 
554
                }
 
555
                compare(clickThroughSpy.count, 0, "click on notification fell through")
 
556
 
 
557
                compare(secondaryIcon.visible, data.secondaryIconVisible, "secondary-icon visibility is incorrect")
 
558
                compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect")
 
559
                compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect")
 
560
                compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect")
 
561
 
 
562
                var audioItem = findInvisibleChild(notification, "sound")
 
563
                compare(audioItem.playbackState, data.hasSound ? Audio.PlayingState : Audio.StoppedState, "Audio has wrong state")
 
564
 
 
565
                if(data.buttonRowVisible) {
 
566
                    var buttonCancel = findChild(buttonRow, "notify_button1")
 
567
                    var buttonAccept = findChild(buttonRow, "notify_button0")
 
568
 
 
569
                    // only test the left/cancel-button if two actions have been passed in
 
570
                    if (data.actions.length == 2) {
 
571
                        tryCompareFunction(function() { mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2); return actionSpy.signalArguments.length > 0; }, true);
 
572
                        compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
 
573
                        actionSpy.clear()
 
574
                    }
 
575
 
 
576
                    // check the tinting of the positive/right button
 
577
                    verify(buttonAccept.color === data.buttonTinted ? "#3fb24f" : "#dddddd", "button has the wrong color-tint")
 
578
 
 
579
                    // click the positive/right button
 
580
                    tryCompareFunction(function() { mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2); return actionSpy.signalArguments.length > 0; }, true);
 
581
                    compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action")
 
582
                    actionSpy.clear()
 
583
                    waitForRendering (notification)
 
584
 
 
585
                    // check if there's a ComboButton created due to more actions being passed
 
586
                    if (data.actions.length > 2) {
 
587
                        var comboButton = findChild(notification, "notify_button2")
 
588
                        tryCompareFunction(function() { return comboButton.expanded == false; }, true);
 
589
 
 
590
                        // click to expand
 
591
                        tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == true; }, true);
 
592
 
 
593
                        // try clicking on choices in expanded comboList
 
594
                        var choiceButton1 = findChild(notification, "notify_button3")
 
595
                        tryCompareFunction(function() { mouseClick(choiceButton1, choiceButton1.width / 2, choiceButton1.height / 2); return actionSpy.signalArguments.length > 0; }, true);
 
596
                        compare(actionSpy.signalArguments[0][0], data.actions[3]["id"], "got wrong id choice action 1")
 
597
                        actionSpy.clear()
 
598
 
 
599
                        var choiceButton2 = findChild(notification, "notify_button4")
 
600
                        tryCompareFunction(function() { mouseClick(choiceButton2, choiceButton2.width / 2, choiceButton2.height / 2); return actionSpy.signalArguments.length > 0; }, true);
 
601
                        compare(actionSpy.signalArguments[0][0], data.actions[4]["id"], "got wrong id choice action 2")
 
602
                        actionSpy.clear()
 
603
 
 
604
                        // click to collapse
 
605
                        //tryCompareFunction(function() { mouseClick(comboButton, comboButton.width - comboButton.__styleInstance.dropDownWidth / 2, comboButton.height / 2); return comboButton.expanded == false; }, true);
 
606
                    } else {
 
607
                        mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2)
 
608
                        compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action")
 
609
                    }
525
610
                }
526
611
            }
527
612
        }