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