Left: | ||
Right: |
OLD | NEW |
---|---|
1 (function() | 1 /* |
2 { | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 let testRunner = null; | 3 * Copyright (C) 2006-2016 Eyeo GmbH |
4 let randomResult = 0.5; | 4 * |
5 | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 let originalInfo; | 6 * it under the terms of the GNU General Public License version 3 as |
7 let info = require("info"); | 7 * published by the Free Software Foundation. |
8 | 8 * |
9 function showNotifications(url) | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 { | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 let shownNotifications = []; | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 function showListener(notification) | 12 * GNU General Public License for more details. |
13 { | 13 * |
14 shownNotifications.push(notification); | 14 * You should have received a copy of the GNU General Public License |
15 Notification.markAsShown(notification.id); | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
16 } | 16 */ |
17 Notification.addShowListener(showListener); | 17 |
18 Notification.showNext(url); | 18 "use strict"; |
19 Notification.removeShowListener(showListener); | 19 |
20 return shownNotifications; | 20 let { |
21 createSandbox, setupTimerAndXMLHttp, setupRandomResult, unexpectedError, Cr | |
22 } = require("./_common"); | |
23 | |
24 let info = null; | |
25 let sandboxedJSON = JSON; | |
kzar
2016/10/05 12:46:30
This variable doesn't seem to be used?
Wladimir Palant
2016/10/05 12:50:42
Right, a left-over from a previous attempt at fixi
| |
26 let Prefs = null; | |
27 let Notification = null; | |
28 | |
29 exports.setUp = function(callback) | |
30 { | |
31 let globals = Object.assign({Array, JSON}, | |
32 setupTimerAndXMLHttp.call(this), setupRandomResult.call(this)); | |
33 | |
34 let sandboxedRequire = createSandbox({globals}); | |
35 | |
kzar
2016/10/05 12:46:30
Nit: This newline is inconsistent with the other t
Wladimir Palant
2016/10/05 12:50:42
Done.
| |
36 ( | |
37 info = sandboxedRequire("./stub-modules/info"), | |
38 {Prefs} = sandboxedRequire("./stub-modules/prefs"), | |
39 {Notification} = sandboxedRequire("../lib/notification") | |
40 ); | |
41 | |
42 callback(); | |
43 }; | |
44 | |
45 function showNotifications(url) | |
46 { | |
47 let shownNotifications = []; | |
48 function showListener(notification) | |
49 { | |
50 shownNotifications.push(notification); | |
51 Notification.markAsShown(notification.id); | |
21 } | 52 } |
22 | 53 Notification.addShowListener(showListener); |
23 module("Notification handling", | 54 Notification.showNext(url); |
24 { | 55 Notification.removeShowListener(showListener); |
25 setup: function() | 56 return shownNotifications; |
26 { | 57 } |
27 testRunner = this; | 58 |
28 | 59 function* pairs(array) |
29 preparePrefs.call(this); | 60 { |
30 setupVirtualTime.call(this, function(wrapTimer) | 61 for (let element1 of array) |
31 { | 62 for (let element2 of array) |
32 let NotificationModule = getModuleGlobal("notification"); | 63 if (element1 != element2) |
33 NotificationModule.downloader._timer = wrapTimer(NotificationModule.down loader._timer); | 64 yield [element1, element2]; |
34 }, "notification", "downloader"); | 65 } |
35 setupVirtualXMLHttp.call(this, "notification", "downloader"); | 66 |
36 | 67 function registerHandler(notifications, checkCallback) |
37 originalInfo = {}; | 68 { |
38 for (let key in info) | 69 this.registerHandler("/notification.json", metadata => |
39 originalInfo[key] = info[key]; | 70 { |
40 | 71 if (checkCallback) |
41 info.addonName = "adblockpluschrome"; | 72 checkCallback(metadata); |
42 info.addonVersion = "1.4.1"; | 73 |
43 info.application = "chrome"; | 74 let notification = { |
44 info.applicationVersion = "27.0"; | 75 version: 55, |
45 info.platform = "chromium"; | 76 notifications |
46 info.platformVersion = "12.0"; | 77 }; |
47 | 78 |
48 Prefs.notificationurl = "http://example.com/notification.json"; | 79 return [Cr.NS_OK, 200, JSON.stringify(notification)]; |
49 Prefs.notificationdata = {}; | |
50 Prefs.notifications_ignoredcategories = []; | |
51 | |
52 // Replace Math.random() function | |
53 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader") ); | |
54 this._origRandom = DownloaderGlobal.Math.random; | |
55 DownloaderGlobal.Math.random = () => randomResult; | |
56 randomResult = 0.5; | |
57 | |
58 let NotificationGlobal = getModuleGlobal("notification"); | |
59 this._origShowListeners = NotificationGlobal.showListeners; | |
60 NotificationGlobal.showListeners = []; | |
61 }, | |
62 | |
63 teardown: function() | |
64 { | |
65 restorePrefs.call(this); | |
66 restoreVirtualTime.call(this); | |
67 restoreVirtualXMLHttp.call(this); | |
68 | |
69 for (let key in originalInfo) | |
70 info[key] = originalInfo[key]; | |
71 | |
72 if (this._origRandom) | |
73 { | |
74 let DownloaderGlobal = Cu.getGlobalForObject(getModuleGlobal("downloader ")); | |
75 DownloaderGlobal.Math.random = this._origRandom; | |
76 delete this._origRandom; | |
77 } | |
78 | |
79 if (this._origShowListeners) | |
80 { | |
81 let NotificationGlobal = getModuleGlobal("notification"); | |
82 NotificationGlobal.showListeners = this._origShowListeners; | |
83 delete this._origShowListeners; | |
84 } | |
85 | |
86 Notification.init(); | |
87 } | |
88 }); | 80 }); |
89 | 81 } |
90 function registerHandler(notifications, checkCallback) | 82 |
91 { | 83 exports.testNoData = function(test) |
92 testRunner.registerHandler("/notification.json", function(metadata) | 84 { |
93 { | 85 test.deepEqual(showNotifications(), [], "No notifications should be returned i f there is no data"); |
94 if (checkCallback) | 86 test.done(); |
95 checkCallback(metadata); | 87 }; |
96 | 88 |
97 let notification = { | 89 exports.testSingleNotification = function(test) |
98 version: 55, | 90 { |
99 notifications: notifications | 91 let information = { |
100 }; | 92 id: 1, |
101 | 93 type: "information", |
102 return [Cr.NS_OK, 200, JSON.stringify(notification)]; | 94 message: {"en-US": "Information"} |
103 }); | 95 }; |
104 } | 96 |
105 | 97 registerHandler.call(this, [information]); |
106 function fixConstructors(object) | 98 this.runScheduledTasks(1).then(() => |
107 { | 99 { |
108 // deepEqual() expects that the constructors used in expected objects and | 100 test.deepEqual(showNotifications(), [information], "The notification is show n"); |
109 // the ones in the actual results are the same. That means that we actually | 101 test.deepEqual(showNotifications(), [], "Informational notifications aren't shown more than once"); |
110 // have to construct our objects in the context of the notification module. | 102 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
111 let JSON = Cu.getGlobalForObject(Notification).JSON; | 103 }; |
112 return JSON.parse(JSON.stringify(object)); | 104 |
113 } | 105 exports.testInformationAndCritical = function(test) |
114 | 106 { |
115 test("No data", function() | 107 let information = { |
116 { | 108 id: 1, |
117 deepEqual(showNotifications(), [], "No notifications should be returned if t here is no data"); | 109 type: "information", |
118 }); | 110 message: {"en-US": "Information"} |
119 | 111 }; |
120 test("Single notification", function() | 112 let critical = { |
121 { | 113 id: 2, |
122 let information = fixConstructors({ | 114 type: "critical", |
115 message: {"en-US": "Critical"} | |
116 }; | |
117 | |
118 registerHandler.call(this, [information, critical]); | |
119 this.runScheduledTasks(1).then(() => | |
120 { | |
121 test.deepEqual(showNotifications(), [critical], "The critical notification i s given priority"); | |
122 test.deepEqual(showNotifications(), [critical], "Critical notifications can be shown multiple times"); | |
123 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
124 }; | |
125 | |
126 exports.testNoType = function(test) | |
127 { | |
128 let information = { | |
129 id: 1, | |
130 message: {"en-US": "Information"} | |
131 }; | |
132 | |
133 registerHandler.call(this, [information]); | |
134 this.runScheduledTasks(1).then(() => | |
135 { | |
136 test.deepEqual(showNotifications(), [information], "The notification is show n"); | |
137 test.deepEqual(showNotifications(), [], "Notification is treated as type inf ormation"); | |
138 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
139 }; | |
140 | |
141 exports.testTargetSelection = {}; | |
142 | |
143 for (let [propName, value, result] of [ | |
144 ["extension", "adblockpluschrome", true], | |
145 ["extension", "adblockplus", false], | |
146 ["extension", "adblockpluschrome2", false], | |
147 ["extensionMinVersion", "1.4", true], | |
148 ["extensionMinVersion", "1.4.1", true], | |
149 ["extensionMinVersion", "1.5", false], | |
150 ["extensionMaxVersion", "1.5", true], | |
151 ["extensionMaxVersion", "1.4.1", true], | |
152 ["extensionMaxVersion", "1.4.*", true], | |
153 ["extensionMaxVersion", "1.4", false], | |
154 ["application", "chrome", true], | |
155 ["application", "firefox", false], | |
156 ["applicationMinVersion", "27.0", true], | |
157 ["applicationMinVersion", "27", true], | |
158 ["applicationMinVersion", "26", true], | |
159 ["applicationMinVersion", "28", false], | |
160 ["applicationMinVersion", "27.1", false], | |
161 ["applicationMaxVersion", "27.0", true], | |
162 ["applicationMaxVersion", "27", true], | |
163 ["applicationMaxVersion", "28", true], | |
164 ["applicationMaxVersion", "26", false], | |
165 ["platform", "chromium", true], | |
166 ["platform", "gecko", false], | |
167 ["platformMinVersion", "12.0", true], | |
168 ["platformMinVersion", "12", true], | |
169 ["platformMinVersion", "11", true], | |
170 ["platformMinVersion", "13", false], | |
171 ["platformMinVersion", "12.1", false], | |
172 ["platformMaxVersion", "12.0", true], | |
173 ["platformMaxVersion", "12", true], | |
174 ["platformMaxVersion", "13", true], | |
175 ["platformMaxVersion", "11", false], | |
176 ]) | |
177 { | |
178 exports.testTargetSelection[`${propName}=${value}`] = function(test) | |
179 { | |
180 let targetInfo = {}; | |
181 targetInfo[propName] = value; | |
182 | |
183 let information = { | |
123 id: 1, | 184 id: 1, |
124 type: "information", | 185 type: "information", |
125 message: {"en-US": "Information"} | 186 message: {"en-US": "Information"}, |
126 }); | 187 targets: [targetInfo] |
127 | 188 }; |
128 registerHandler([information]); | 189 |
129 testRunner.runScheduledTasks(1); | 190 registerHandler.call(this, [information]); |
130 | 191 this.runScheduledTasks(1).then(() => |
131 deepEqual(showNotifications(), [information], "The notification is shown"); | 192 { |
132 deepEqual(showNotifications(), [], "Informational notifications aren't shown more than once"); | 193 let expected = (result ? [information] : []); |
133 }); | 194 test.deepEqual(showNotifications(), expected, "Selected notification for " + JSON.stringify(information.targets)); |
134 | 195 test.deepEqual(showNotifications(), [], "No notification on second call"); |
135 test("Information and critical", function() | 196 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
136 { | 197 }; |
137 let information = fixConstructors({ | 198 } |
199 | |
200 exports.testMultipleTargets = {}; | |
201 | |
202 for (let [[propName1, value1, result1], [propName2, value2, result2]] of pairs([ | |
203 ["extension", "adblockpluschrome", true], | |
204 ["extension", "adblockplus", false], | |
205 ["extensionMinVersion", "1.4", true], | |
206 ["extensionMinVersion", "1.5", false], | |
207 ["application", "chrome", true], | |
208 ["application", "firefox", false], | |
209 ["applicationMinVersion", "27", true], | |
210 ["applicationMinVersion", "28", false], | |
211 ["platform", "chromium", true], | |
212 ["platform", "gecko", false], | |
213 ["platformMinVersion", "12", true], | |
214 ["platformMinVersion", "13", false], | |
215 ])) | |
216 { | |
217 exports.testMultipleTargets[`${propName1}=${value1},${propName2}=${value2}`] = function(test) | |
218 { | |
219 let targetInfo1 = {}; | |
220 targetInfo1[propName1] = value1; | |
221 let targetInfo2 = {}; | |
222 targetInfo2[propName2] = value2; | |
223 | |
224 let information = { | |
138 id: 1, | 225 id: 1, |
139 type: "information", | 226 type: "information", |
140 message: {"en-US": "Information"} | 227 message: {"en-US": "Information"}, |
141 }); | 228 targets: [targetInfo1, targetInfo2] |
142 let critical = fixConstructors({ | 229 }; |
143 id: 2, | 230 |
144 type: "critical", | 231 registerHandler.call(this, [information]); |
145 message: {"en-US": "Critical"} | 232 this.runScheduledTasks(1).then(() => |
146 }); | 233 { |
147 | 234 let expected = (result1 || result2 ? [information] : []) |
148 registerHandler([information, critical]); | 235 test.deepEqual(showNotifications(), expected, "Selected notification for " + JSON.stringify(information.targets)); |
149 testRunner.runScheduledTasks(1); | 236 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
150 | 237 } |
151 deepEqual(showNotifications(), [critical], "The critical notification is giv en priority"); | 238 } |
152 deepEqual(showNotifications(), [critical], "Critical notifications can be sh own multiple times"); | 239 |
240 exports.testParametersSent = function(test) | |
241 { | |
242 Prefs.notificationdata = { | |
243 data: { | |
244 version: "3" | |
245 }, | |
246 }; | |
247 | |
248 let parameters = null; | |
249 registerHandler.call(this, [], function(metadata) | |
250 { | |
251 parameters = decodeURI(metadata.queryString); | |
153 }); | 252 }); |
154 | 253 this.runScheduledTasks(1).then(() => |
155 test("No type", function() | 254 { |
156 { | 255 test.equal(parameters, |
157 let information = fixConstructors({ | |
158 id: 1, | |
159 message: {"en-US": "Information"} | |
160 }); | |
161 | |
162 registerHandler([information]); | |
163 testRunner.runScheduledTasks(1); | |
164 | |
165 deepEqual(showNotifications(), [information], "The notification is shown"); | |
166 deepEqual(showNotifications(), [], "Notification is treated as type informat ion"); | |
167 }); | |
168 | |
169 test("Target selection", function() | |
170 { | |
171 let targets = [ | |
172 ["extension", "adblockpluschrome", true], | |
173 ["extension", "adblockplus", false], | |
174 ["extension", "adblockpluschrome2", false], | |
175 ["extensionMinVersion", "1.4", true], | |
176 ["extensionMinVersion", "1.4.1", true], | |
177 ["extensionMinVersion", "1.5", false], | |
178 ["extensionMaxVersion", "1.5", true], | |
179 ["extensionMaxVersion", "1.4.1", true], | |
180 ["extensionMaxVersion", "1.4.*", true], | |
181 ["extensionMaxVersion", "1.4", false], | |
182 ["application", "chrome", true], | |
183 ["application", "firefox", false], | |
184 ["applicationMinVersion", "27.0", true], | |
185 ["applicationMinVersion", "27", true], | |
186 ["applicationMinVersion", "26", true], | |
187 ["applicationMinVersion", "28", false], | |
188 ["applicationMinVersion", "27.1", false], | |
189 ["applicationMaxVersion", "27.0", true], | |
190 ["applicationMaxVersion", "27", true], | |
191 ["applicationMaxVersion", "28", true], | |
192 ["applicationMaxVersion", "26", false], | |
193 ["platform", "chromium", true], | |
194 ["platform", "gecko", false], | |
195 ["platformMinVersion", "12.0", true], | |
196 ["platformMinVersion", "12", true], | |
197 ["platformMinVersion", "11", true], | |
198 ["platformMinVersion", "13", false], | |
199 ["platformMinVersion", "12.1", false], | |
200 ["platformMaxVersion", "12.0", true], | |
201 ["platformMaxVersion", "12", true], | |
202 ["platformMaxVersion", "13", true], | |
203 ["platformMaxVersion", "11", false], | |
204 ]; | |
205 | |
206 for (let [propName, value, result] of targets) | |
207 { | |
208 let targetInfo = {}; | |
209 targetInfo[propName] = value; | |
210 | |
211 let information = fixConstructors({ | |
212 id: 1, | |
213 type: "information", | |
214 message: {"en-US": "Information"}, | |
215 targets: [targetInfo] | |
216 }); | |
217 | |
218 Prefs.notificationdata = {}; | |
219 registerHandler([information]); | |
220 testRunner.runScheduledTasks(1); | |
221 | |
222 let expected = (result ? [information] : []); | |
223 deepEqual(showNotifications(), expected, "Selected notification for " + JS ON.stringify(information.targets)); | |
224 deepEqual(showNotifications(), [], "No notification on second call"); | |
225 } | |
226 }); | |
227 | |
228 test("Multiple targets", function() | |
229 { | |
230 let targets = [ | |
231 ["extension", "adblockpluschrome", true], | |
232 ["extension", "adblockplus", false], | |
233 ["extensionMinVersion", "1.4", true], | |
234 ["extensionMinVersion", "1.5", false], | |
235 ["application", "chrome", true], | |
236 ["application", "firefox", false], | |
237 ["applicationMinVersion", "27", true], | |
238 ["applicationMinVersion", "28", false], | |
239 ["platform", "chromium", true], | |
240 ["platform", "gecko", false], | |
241 ["platformMinVersion", "12", true], | |
242 ["platformMinVersion", "13", false], | |
243 ]; | |
244 | |
245 function pairs(array) | |
246 { | |
247 for (let element1 of array) | |
248 for (let element2 of array) | |
249 if (element1 != element2) | |
250 yield [element1, element2]; | |
251 } | |
252 | |
253 for (let [[propName1, value1, result1], [propName2, value2, result2]] in pai rs(targets)) | |
254 { | |
255 let targetInfo1 = {}; | |
256 targetInfo1[propName1] = value1; | |
257 let targetInfo2 = {}; | |
258 targetInfo2[propName2] = value2; | |
259 | |
260 let information = fixConstructors({ | |
261 id: 1, | |
262 type: "information", | |
263 message: {"en-US": "Information"}, | |
264 targets: [targetInfo1, targetInfo2] | |
265 }); | |
266 | |
267 Prefs.notificationdata = {}; | |
268 registerHandler([information]); | |
269 testRunner.runScheduledTasks(1); | |
270 | |
271 let expected = (result1 || result2 ? [information] : []) | |
272 deepEqual(showNotifications(), expected, "Selected notification for " + JS ON.stringify(information.targets)); | |
273 } | |
274 }); | |
275 | |
276 test("Parameters sent", function() | |
277 { | |
278 Prefs.notificationdata = { | |
279 data: { | |
280 version: "3" | |
281 }, | |
282 }; | |
283 | |
284 let parameters = null; | |
285 registerHandler([], function(metadata) | |
286 { | |
287 parameters = decodeURI(metadata.queryString); | |
288 }); | |
289 testRunner.runScheduledTasks(1); | |
290 | |
291 equal(parameters, | |
292 "addonName=adblockpluschrome&addonVersion=1.4.1&application=chrome&app licationVersion=27.0&platform=chromium&platformVersion=12.0&lastVersion=3&downlo adCount=0", | 256 "addonName=adblockpluschrome&addonVersion=1.4.1&application=chrome&app licationVersion=27.0&platform=chromium&platformVersion=12.0&lastVersion=3&downlo adCount=0", |
293 "The correct parameters are sent to the server"); | 257 "The correct parameters are sent to the server"); |
258 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
259 }; | |
260 | |
261 exports.testExpirationInterval = {}; | |
262 | |
263 let initialDelay = 1 / 60; | |
264 for (let currentTest of [ | |
265 { | |
266 randomResult: 0.5, | |
267 requests: [initialDelay, initialDelay + 24, initialDelay + 48] | |
268 }, | |
269 { | |
270 randomResult: 0, // Changes interval by factor 0.8 (19.2 hours) | |
271 requests: [initialDelay, initialDelay + 20, initialDelay + 40] | |
272 }, | |
273 { | |
274 randomResult: 1, // Changes interval by factor 1.2 (28.8 hours) | |
275 requests: [initialDelay, initialDelay + 29, initialDelay + 58] | |
276 }, | |
277 { | |
278 randomResult: 0.25, // Changes interval by factor 0.9 (21.6 hours) | |
279 requests: [initialDelay, initialDelay + 22, initialDelay + 44] | |
280 }, | |
281 { | |
282 randomResult: 0.5, | |
283 skipAfter: initialDelay + 5, | |
284 skip: 10, // Short break should not increase soft expiration | |
285 requests: [initialDelay, initialDelay + 24] | |
286 }, | |
287 { | |
288 randomResult: 0.5, | |
289 skipAfter: initialDelay + 5, | |
290 skip: 30, // Long break should increase soft expiration, hitti ng hard expiration | |
291 requests: [initialDelay, initialDelay + 48] | |
292 } | |
293 ]) | |
294 { | |
295 let testId = "Math.random() returning " + currentTest.randomResult; | |
296 if (typeof currentTest.skip != "number") | |
297 testId += " skipping " + currentTest.skip + " hours after " + currentTest.sk ipAfter + " hours"; | |
298 exports.testExpirationInterval[testId] = function(test) | |
299 { | |
300 let requests = []; | |
301 registerHandler.call(this, [], metadata => requests.push(this.getTimeOffset( ))); | |
302 | |
303 this.randomResult = currentTest.randomResult; | |
304 | |
305 let maxHours = Math.round(Math.max.apply(null, currentTest.requests)) + 1; | |
306 this.runScheduledTasks(maxHours, currentTest.skipAfter, currentTest.skip).th en(() => | |
307 { | |
308 test.deepEqual(requests, currentTest.requests, "Requests"); | |
309 }).catch(unexpectedError.bind(test)).then(() => test.done()); | |
310 }; | |
311 } | |
312 | |
313 exports.testUsingSeverityInsteadOfType = function(test) | |
314 { | |
315 let severityNotification = { | |
316 id: 1, | |
317 severity: "information", | |
318 message: {"en-US": "Information"} | |
319 }; | |
320 | |
321 function listener(name) | |
322 { | |
323 if (name !== "notificationdata") | |
324 return; | |
325 | |
326 Prefs.removeListener(listener); | |
327 let notification = Prefs.notificationdata.data.notifications[0]; | |
328 test.ok(!("severity" in notification), "Severity property was removed"); | |
329 test.ok("type" in notification, "Type property was added"); | |
330 test.equal(notification.type, severityNotification.severity, "Type property has correct value"); | |
331 test.done(); | |
332 } | |
333 Prefs.addListener(listener); | |
334 | |
335 let responseText = JSON.stringify({ | |
336 notifications: [severityNotification] | |
294 }); | 337 }); |
295 | 338 Notification._onDownloadSuccess({}, responseText, function() {}, function() {} ); |
296 test("Expiration interval", function() | 339 }; |
297 { | 340 |
298 let initialDelay = 1 / 60; | 341 exports.testURLSpecificNotification = function(test) |
299 let tests = [ | 342 { |
300 { | 343 let withURLFilterFoo = { |
301 randomResult: 0.5, | 344 id: 1, |
302 requests: [initialDelay, initialDelay + 24, initialDelay + 48] | 345 urlFilters: ["foo.com$document"] |
303 }, | 346 }; |
304 { | 347 let withoutURLFilter = { |
305 randomResult: 0, // Changes interval by factor 0.8 (19.2 hours) | 348 id: 2 |
306 requests: [initialDelay, initialDelay + 20, initialDelay + 40] | 349 }; |
307 }, | 350 let withURLFilterBar = { |
308 { | 351 id: 3, |
309 randomResult: 1, // Changes interval by factor 1.2 (28.8 hours) | 352 urlFilters: ["bar.com$document"] |
310 requests: [initialDelay, initialDelay + 29, initialDelay + 58] | 353 }; |
311 }, | 354 let subdomainURLFilter = { |
312 { | 355 id: 4, |
313 randomResult: 0.25, // Changes interval by factor 0.9 (21.6 hours) | 356 urlFilters: ["||example.com$document"] |
314 requests: [initialDelay, initialDelay + 22, initialDelay + 44] | 357 }; |
315 }, | 358 |
316 { | 359 registerHandler.call(this, [ |
317 randomResult: 0.5, | 360 withURLFilterFoo, |
318 skipAfter: initialDelay + 5, | 361 withoutURLFilter, |
319 skip: 10, // Short break should not increase soft expirati on | 362 withURLFilterBar, |
320 requests: [initialDelay, initialDelay + 24] | 363 subdomainURLFilter |
321 }, | 364 ]); |
322 { | 365 this.runScheduledTasks(1).then(() => |
323 randomResult: 0.5, | 366 { |
324 skipAfter: initialDelay + 5, | 367 test.deepEqual(showNotifications(), [withoutURLFilter], "URL-specific notifi cations are skipped"); |
325 skip: 30, // Long break should increase soft expiration, h itting hard expiration | 368 test.deepEqual(showNotifications("http://foo.com"), [withURLFilterFoo], "URL -specific notification is retrieved"); |
326 requests: [initialDelay, initialDelay + 48] | 369 test.deepEqual(showNotifications("http://foo.com"), [], "URL-specific notifi cation is not retrieved"); |
327 } | 370 test.deepEqual(showNotifications("http://www.example.com"), [subdomainURLFil ter], "URL-specific notification matches subdomain"); |
328 ]; | 371 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
329 | 372 }; |
330 let requests = []; | 373 |
331 registerHandler([], (metadata) => requests.push(testRunner.getTimeOffset())) ; | 374 exports.testGlobalOptOut = function(test) |
332 for (let test of tests) | 375 { |
333 { | 376 Notification.toggleIgnoreCategory("*", true); |
334 Prefs.notificationdata = {}; | 377 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Force enabl e global opt-out"); |
335 requests = []; | 378 Notification.toggleIgnoreCategory("*", true); |
336 randomResult = test.randomResult; | 379 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Force enabl e global opt-out (again)"); |
337 | 380 Notification.toggleIgnoreCategory("*", false); |
338 let maxHours = Math.round(Math.max.apply(null, test.requests)) + 1; | 381 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Force disab le global opt-out"); |
339 testRunner.runScheduledTasks(maxHours, test.skipAfter, test.skip); | 382 Notification.toggleIgnoreCategory("*", false); |
340 | 383 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Force disab le global opt-out (again)"); |
341 let skipAddendum = (typeof test.skip != "number" ? "" : " skipping " + tes t.skip + " hours after " + test.skipAfter + " hours"); | 384 Notification.toggleIgnoreCategory("*"); |
342 deepEqual(requests, test.requests, "Requests with Math.random() returning " + randomResult + skipAddendum); | 385 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Toggle enab le global opt-out"); |
343 } | 386 Notification.toggleIgnoreCategory("*"); |
344 }); | 387 test.ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Toggle disa ble global opt-out"); |
345 | 388 |
346 test("Uses severity instead of type", 3, function() | 389 Prefs.notifications_showui = false; |
347 { | 390 Notification.toggleIgnoreCategory("*", false); |
348 let severityNotification = { | 391 test.ok(!Prefs.notifications_showui, "Opt-out UI will not be shown if global o pt-out hasn't been enabled yet"); |
349 id: 1, | 392 Notification.toggleIgnoreCategory("*", true); |
350 severity: "information", | 393 test.ok(Prefs.notifications_showui, "Opt-out UI will be shown after enabling g lobal opt-out"); |
351 message: {"en-US": "Information"} | 394 Notification.toggleIgnoreCategory("*", false); |
352 }; | 395 test.ok(Prefs.notifications_showui, "Opt-out UI will be shown after enabling g lobal opt-out even if it got disabled again"); |
353 | 396 |
354 function listener(name) | 397 let information = { |
355 { | 398 id: 1, |
356 if (name !== "notificationdata") | 399 type: "information" |
357 return; | 400 }; |
358 | 401 let critical = { |
359 Prefs.removeListener(listener); | 402 id: 2, |
360 let notification = Prefs.notificationdata.data.notifications[0]; | 403 type: "critical" |
361 ok(!("severity" in notification), "Severity property was removed"); | 404 }; |
362 ok("type" in notification, "Type property was added"); | 405 |
363 equal(notification.type, severityNotification.severity, "Type property has correct value"); | 406 Notification.toggleIgnoreCategory("*", true); |
364 } | 407 registerHandler.call(this, [information]); |
365 Prefs.addListener(listener); | 408 this.runScheduledTasks(1).then(() => |
366 | 409 { |
367 let responseText = JSON.stringify({ | 410 test.deepEqual(showNotifications(), [], "Information notifications are ignor ed after enabling global opt-out"); |
368 notifications: [severityNotification] | |
369 }); | |
370 Notification._onDownloadSuccess({}, responseText, function() {}, function() {}); | |
371 }); | |
372 | |
373 test("URL-specific notification", function() | |
374 { | |
375 let withURLFilterFoo = fixConstructors({ | |
376 id: 1, | |
377 urlFilters: ["foo.com$document"] | |
378 }); | |
379 let withoutURLFilter = fixConstructors({ | |
380 id: 2 | |
381 }); | |
382 let withURLFilterBar = fixConstructors({ | |
383 id: 3, | |
384 urlFilters: ["bar.com$document"] | |
385 }); | |
386 let subdomainURLFilter = fixConstructors({ | |
387 id: 4, | |
388 urlFilters: ["||example.com$document"] | |
389 }); | |
390 | |
391 registerHandler([ | |
392 withURLFilterFoo, | |
393 withoutURLFilter, | |
394 withURLFilterBar, | |
395 subdomainURLFilter | |
396 ]); | |
397 testRunner.runScheduledTasks(1); | |
398 | |
399 deepEqual(showNotifications(), [withoutURLFilter], "URL-specific notificatio ns are skipped"); | |
400 deepEqual(showNotifications("http://foo.com"), [withURLFilterFoo], "URL-spec ific notification is retrieved"); | |
401 deepEqual(showNotifications("http://foo.com"), [], "URL-specific notificatio n is not retrieved"); | |
402 deepEqual(showNotifications("http://www.example.com"), [subdomainURLFilter], "URL-specific notification matches subdomain"); | |
403 }); | |
404 | |
405 test("Global opt-out", function() | |
406 { | |
407 Notification.toggleIgnoreCategory("*", true); | |
408 ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Force enable g lobal opt-out"); | |
409 Notification.toggleIgnoreCategory("*", true); | |
410 ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Force enable g lobal opt-out (again)"); | |
411 Notification.toggleIgnoreCategory("*", false); | 411 Notification.toggleIgnoreCategory("*", false); |
412 ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Force disable global opt-out"); | 412 test.deepEqual(showNotifications(), [information], "Information notification s are shown after disabling global opt-out"); |
413 Notification.toggleIgnoreCategory("*", false); | |
414 ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Force disable global opt-out (again)"); | |
415 Notification.toggleIgnoreCategory("*"); | |
416 ok(Prefs.notifications_ignoredcategories.indexOf("*") != -1, "Toggle enable global opt-out"); | |
417 Notification.toggleIgnoreCategory("*"); | |
418 ok(Prefs.notifications_ignoredcategories.indexOf("*") == -1, "Toggle disable global opt-out"); | |
419 | |
420 Prefs.notifications_showui = false; | |
421 Notification.toggleIgnoreCategory("*", false); | |
422 ok(!Prefs.notifications_showui, "Opt-out UI will not be shown if global opt- out hasn't been enabled yet"); | |
423 Notification.toggleIgnoreCategory("*", true); | |
424 ok(Prefs.notifications_showui, "Opt-out UI will be shown after enabling glob al opt-out"); | |
425 Notification.toggleIgnoreCategory("*", false); | |
426 ok(Prefs.notifications_showui, "Opt-out UI will be shown after enabling glob al opt-out even if it got disabled again"); | |
427 | |
428 let information = fixConstructors({ | |
429 id: 1, | |
430 type: "information" | |
431 }); | |
432 let critical = fixConstructors({ | |
433 id: 2, | |
434 type: "critical" | |
435 }); | |
436 | |
437 Notification.toggleIgnoreCategory("*", true); | |
438 registerHandler([information]); | |
439 testRunner.runScheduledTasks(1); | |
440 | |
441 deepEqual(showNotifications(), [], "Information notifications are ignored af ter enabling global opt-out"); | |
442 Notification.toggleIgnoreCategory("*", false); | |
443 deepEqual(showNotifications(), [information], "Information notifications are shown after disabling global opt-out"); | |
444 | 413 |
445 Notification.toggleIgnoreCategory("*", true); | 414 Notification.toggleIgnoreCategory("*", true); |
446 Prefs.notificationdata = {}; | 415 Prefs.notificationdata = {}; |
447 registerHandler([critical]); | 416 registerHandler.call(this, [critical]); |
448 testRunner.runScheduledTasks(1); | 417 return this.runScheduledTasks(1); |
449 | 418 }).then(() => |
450 deepEqual(showNotifications(), [critical], "Critical notifications are not i gnored"); | 419 { |
451 }); | 420 test.deepEqual(showNotifications(), [critical], "Critical notifications are not ignored"); |
452 | 421 }).catch(unexpectedError.bind(test)).then(() => test.done()); |
453 module("Notification localization"); | 422 }; |
454 | 423 |
455 test("Message without localization", function() | 424 exports.testMessageWithoutLocalization = function(test) |
456 { | 425 { |
457 let notification = {message: "non-localized"}; | 426 let notification = {message: "non-localized"}; |
458 let texts = Notification.getLocalizedTexts(notification, "en-US"); | 427 let texts = Notification.getLocalizedTexts(notification, "en-US"); |
459 equal(texts.message, "non-localized"); | 428 test.equal(texts.message, "non-localized"); |
460 }); | 429 test.done(); |
461 | 430 }; |
462 test("Language only", function() | 431 |
463 { | 432 exports.testLanguageOnly = function(test) |
464 let notification = {message: {fr: "fr"}}; | 433 { |
465 let texts = Notification.getLocalizedTexts(notification, "fr"); | 434 let notification = {message: {fr: "fr"}}; |
466 equal(texts.message, "fr"); | 435 let texts = Notification.getLocalizedTexts(notification, "fr"); |
467 texts = Notification.getLocalizedTexts(notification, "fr-CA"); | 436 test.equal(texts.message, "fr"); |
468 equal(texts.message, "fr"); | 437 texts = Notification.getLocalizedTexts(notification, "fr-CA"); |
469 }); | 438 test.equal(texts.message, "fr"); |
470 | 439 test.done(); |
471 test("Language and country", function() | 440 }; |
472 { | 441 |
473 let notification = {message: {fr: "fr", "fr-CA": "fr-CA"}}; | 442 exports.testLanguageAndCountry = function(test) |
474 let texts = Notification.getLocalizedTexts(notification, "fr-CA"); | 443 { |
475 equal(texts.message, "fr-CA"); | 444 let notification = {message: {fr: "fr", "fr-CA": "fr-CA"}}; |
476 texts = Notification.getLocalizedTexts(notification, "fr"); | 445 let texts = Notification.getLocalizedTexts(notification, "fr-CA"); |
477 equal(texts.message, "fr"); | 446 test.equal(texts.message, "fr-CA"); |
478 }); | 447 texts = Notification.getLocalizedTexts(notification, "fr"); |
479 | 448 test.equal(texts.message, "fr"); |
480 test("Missing translation", function() | 449 test.done(); |
481 { | 450 }; |
482 let notification = {message: {"en-US": "en-US"}}; | 451 |
483 let texts = Notification.getLocalizedTexts(notification, "fr"); | 452 exports.testMissingTranslation = function(test) |
484 equal(texts.message, "en-US"); | 453 { |
485 }); | 454 let notification = {message: {"en-US": "en-US"}}; |
486 })(); | 455 let texts = Notification.getLocalizedTexts(notification, "fr"); |
456 test.equal(texts.message, "en-US"); | |
457 test.done(); | |
458 }; | |
OLD | NEW |