Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / test / data / extensions / api_test / notifications / api / basic_usage / background.js
blob001f6db088ffb49eb32062a725f77a13da44e074
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 const notifications = chrome.notifications;
7 const red_dot = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA" +
8     "AAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO" +
9     "9TXL0Y4OHwAAAABJRU5ErkJggg==";
11 function createBigImageUrl() {
12   var canvas = document.createElement('canvas');
13   canvas.width = 5000;
14   canvas.height = 5000;
15   var ctx = canvas.getContext('2d');
16   ctx.fillStyle = "rgb(200, 0, 0)";
17   ctx.fillRect(10, 20, 30, 40);
19   return canvas.toDataURL();
22 var basicNotificationOptions = {
23   type: "basic",
24   title: "Basic title",
25   message: "Basic message",
26   iconUrl: red_dot
29 function create(id, options) {
30   return new Promise(function (resolve, reject) {
31     notifications.create(id, options, function (id) {
32       if (chrome.runtime.lastError) {
33         reject(new Error("Unable to create notification"));
34         return;
35       }
36       resolve(id);
37       return;
38     });
39   });
42 function update(id, options) {
43   return new Promise(function (resolve, reject) {
44     notifications.update(id, options, function (ok) {
45       if (chrome.runtime.lastError || !ok) {
46         reject(new Error("Unable to update notification"));
47         return;
48       }
49       resolve(ok);
50       return;
51     });
52   });
55 function clear(id) {
56   return new Promise(function (resolve, reject) {
57     notifications.clear(id, function (ok) {
58       if (chrome.runtime.lastError || !ok) {
59         reject(new Error("Unable to clear notification"));
60         return;
61       }
62       resolve(ok);
63       return;
64     });
65   });
68 function getAll() {
69   return new Promise(function (resolve, reject) {
70     notifications.getAll(function (ids) {
71       if (chrome.runtime.lastError) {
72         reject(new Error(chrome.runtime.lastError.message));
73         return;
74       }
76       if (ids === undefined) {
77         resolve([]);
78         return
79       }
81       var id_list = Object.keys(ids);
82       resolve(id_list);
83     });
84   });
87 function clearAll() {
88   return getAll().then(function (ids) {
89     var idPromises = ids.map(function (id) { return clear(id); });
90     return Promise.all(idPromises);
91   });
94 function succeedTest(testName) {
95   return function () {
96     return clearAll().then(
97         function () { chrome.test.succeed(testName); },
98         function (error) {
99           console.log("Unknown error in clearAll: " +
100                       JSON.stringify(arguments));
101         });
102   };
105 function failTest(testName) {
106   return function () {
107     return clearAll().then(
108         function () { chrome.test.fail(testName); },
109         function (error) {
110           console.log("Unknown error in clearAll: " +
111                       JSON.stringify(error.message));
112         });
113   };
116 function testIdUsage() {
117   var testName = "testIdUsage";
118   console.log("Starting testIdUsage.");
119   var succeed = succeedTest(testName);
120   var fail = failTest(testName);
122   var createNotification = function (idString) {
123     var options = {
124       type: "basic",
125       iconUrl: red_dot,
126       title: "Attention!",
127       message: "Check out Cirque du Soleil"
128     };
130     return create(idString, options);
131   };
133   var updateNotification = function (idString) {
134     var options = { title: "!", message: "!" };
135     return update(idString, options);
136   };
138   // Should successfully create the notification
139   createNotification("foo")
140     // And update it.
141     .then(updateNotification)
142     .catch(fail)
143     // Next try to update a non-existent notification.
144     .then(function () { return updateNotification("foo2"); })
145     // And fail if it returns true.
146     .then(fail)
147     // Next try to clear a non-existent notification.
148     .catch(function () { return clear("foo2"); })
149     .then(fail)
150     // And finally clear the original notification.
151     .catch(function () { return clear("foo"); })
152     .catch(fail)
153     .then(succeed);
156 function testBaseFormat() {
157   var testName = "testBaseFormat";
158   console.log("Starting " + testName);
159   var succeed = succeedTest(testName);
160   var fail = failTest(testName);
162   var createNotificationWithout = function(toDelete) {
163     var options = {
164       type: "basic",
165       iconUrl: red_dot,
166       title: "Attention!",
167       message: "Check out Cirque du Soleil",
168       contextMessage: "Foobar.",
169       priority: 1,
170       eventTime: 123457896.12389,
171       expandedMessage: "This is a longer expanded message.",
172       isClickable: true
173     };
175     for (var i = 0; i < toDelete.length; i++) {
176       delete options[toDelete[i]];
177     }
179     return create("", options);
180   };
182   // Construct some exclusion lists.  The |createNotificationWithout| function
183   // starts with a complex notification and then deletes items in this list.
184   var basicNotification= [
185     "buttons",
186     "items",
187     "progress",
188     "imageUrl"
189   ];
190   var bareNotification = basicNotification.concat([
191     "priority",
192     "eventTime",
193     "expandedMessage",
194   ]);
195   var basicNoType = basicNotification.concat(["type"]);
196   var basicNoIcon = basicNotification.concat(["iconUrl"]);
197   var basicNoTitle = basicNotification.concat(["title"]);
198   var basicNoMessage = basicNotification.concat(["message"]);
200   // Try creating a basic notification with just some of the fields.
201   createNotificationWithout(basicNotification)
202     // Try creating a basic notification with all possible fields.
203     .then(function () { return createNotificationWithout([]); })
204     // Try creating a basic notification with the minimum in fields.
205     .then(function () { return createNotificationWithout(bareNotification); })
206     // After this line we are checking to make sure that there is an error
207     // when notifications are created without the proper fields.
208     .catch(fail)
209     // Error if no type.
210     .then(function () { return createNotificationWithout(basicNoType) })
211     // Error if no icon.
212     .catch(function () { return createNotificationWithout(basicNoIcon) })
213     // Error if no title.
214     .catch(function () { return createNotificationWithout(basicNoTitle) })
215     // Error if no message.
216     .catch(function () { return createNotificationWithout(basicNoMessage) })
217     .then(fail, succeed);
220 function testListItem() {
221   var testName = "testListItem";
222   console.log("Starting " + testName);
223   var succeed = succeedTest(testName);
224   var fail = failTest(testName);
226   var item = { title: "Item title.", message: "Item message." };
227   var options = {
228     type: "list",
229     iconUrl: red_dot,
230     title: "Attention!",
231     message: "Check out Cirque du Soleil",
232     contextMessage: "Foobar.",
233     priority: 1,
234     eventTime: 123457896.12389,
235     items: [item, item, item, item, item],
236     isClickable: true
237   };
238   create("id", options).then(succeed, fail);
241 function arrayEquals(a, b) {
242   if (a === b) return true;
243   if (a == null || b == null) return false;
244   if (a.length !== b.length) return false;
246   for (var i = 0; i < a.length; i++) {
247     if (a[i] !== b[i]) return false;
248   }
249   return true;
252 function testGetAll() {
253   var testName = "testGetAll";
254   console.log("Starting " + testName);
255   var succeed = succeedTest(testName);
256   var fail = failTest(testName);
257   var in_ids = ["a", "b", "c", "d"];
259   // First do a get all, make sure the list is empty.
260   getAll()
261     .then(function (ids) {
262         chrome.test.assertEq(0, ids.length);
263     })
264     // Then create a bunch of notifications.
265     .then(function () {
266       var newNotifications = in_ids.map(function (id) {
267         return create(id, basicNotificationOptions);
268       });
269       return Promise.all(newNotifications);
270     })
271     // Try getAll again.
272     .then(function () { return getAll(); })
273     // Check that the right set of notifications is in the center.
274     .then(function (ids) {
275       chrome.test.assertEq(4, ids.length);
276       chrome.test.assertTrue(arrayEquals(ids, in_ids));
277       succeed();
278     }, fail);
281 function testProgress() {
282   var testName = "testProgress";
283   console.log("Starting " + testName);
284   var succeed = succeedTest(testName);
285   var fail = failTest(testName);
286   var progressOptions = {
287     type: "progress",
288     title: "Basic title",
289     message: "Basic message",
290     iconUrl: red_dot,
291     progress: 30
292   };
294   // First, create a basic progress notification.
295   create("progress", progressOptions)
296     // and update it to have a different progress level.
297     .then(function () { return update("progress", { progress: 60 }); })
298     // If either of the above failed, the test fails.
299     .catch(fail)
300     // Now the following parts should all cause an error:
301     // First update the progress to a low value, out-of-range
302     .then(function () { return update("progress", { progress: -10 }); })
303     // First update the progress to a high value, out-of-range
304     .then(fail, function () { return update("progress", { progress: 101 }); })
305     .then(function () { return clear("progress"); })
306     // Finally try to create a notification that has a progress value but not
307     // progress type.
308     .then(fail, function () {
309       progressOptions.type = "basic";
310       return create("progress", progressOptions);
311     }).then(fail, succeed);
314 function testLargeImage() {
315   var testName = "testLargeImage";
316   console.log("Starting " + testName);
317   var succeed = succeedTest(testName);
318   var fail = failTest(testName);
319   var options = {
320     type: "basic",
321     title: "Basic title",
322     message: "Basic message",
323     iconUrl: createBigImageUrl(),
324   };
325   create("largeImage", options).then(succeed, fail);
328 function testOptionalParameters() {
329   var testName = "testOptionalParameters";
330   var succeed = succeedTest(testName);
331   var fail = failTest(testName);
332   function createCallback(notificationId) {
333     new Promise(function() {
334       chrome.test.assertNoLastError();
335       chrome.test.assertEq("string", typeof notificationId);
336       // Optional callback - should run without problems
337       chrome.notifications.clear(notificationId);
338       // Note: The point of the previous line is to show that a callback can be
339       // optional. Because .clear is asynchronous, we have to be careful with
340       // calling .clear again. Since .clear is processed in order, calling
341       // clear() synchronously is okay.
342       // If this assumption does not hold and leaks to flaky tests, file a bug
343       // report and/or put the following call in a setTimeout call.
345       // The notification should not exist any more, so clear() should fail.
346       clear(notificationId).then(fail, succeed);
347     }).then(null, fail);
348   }
349   // .create should succeed even when notificationId is omitted.
350   chrome.notifications.create(basicNotificationOptions, createCallback);
353 chrome.test.runTests([
354     testIdUsage, testBaseFormat, testListItem, testGetAll, testProgress,
355     testLargeImage, testOptionalParameters