Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/ */
4 MARIONETTE_TIMEOUT = 40000;
6 SpecialPowers.addPermission("sms", true, document);
7 SpecialPowers.setBoolPref("dom.sms.enabled", true);
9 let manager = window.navigator.mozMobileMessage;
10 ok(manager instanceof MozMobileMessageManager,
11 "manager is instance of " + manager.constructor);
13 let pendingEmulatorCmdCount = 0;
14 function sendSmsToEmulator(from, text, callback) {
15 ++pendingEmulatorCmdCount;
17 let cmd = "sms send " + from + " " + text;
18 runEmulatorCmd(cmd, function(result) {
19 --pendingEmulatorCmdCount;
21 callback(result[0] == "OK");
22 });
23 }
25 let tasks = {
26 // List of test fuctions. Each of them should call |tasks.next()| when
27 // completed or |tasks.finish()| to jump to the last one.
28 _tasks: [],
29 _nextTaskIndex: 0,
31 push: function(func) {
32 this._tasks.push(func);
33 },
35 next: function() {
36 let index = this._nextTaskIndex++;
37 let task = this._tasks[index];
38 try {
39 task.apply(null, Array.slice(arguments));
40 } catch (ex) {
41 ok(false, "test task[" + index + "] throws: " + ex);
42 // Run last task as clean up if possible.
43 if (index != this._tasks.length - 1) {
44 this.finish();
45 }
46 }
47 },
49 finish: function() {
50 this._tasks[this._tasks.length - 1]();
51 },
53 run: function() {
54 this.next();
55 }
56 };
58 function getAllMessages(callback, filter, reverse) {
59 if (!filter) {
60 filter = new MozSmsFilter;
61 }
62 let messages = [];
63 let request = manager.getMessages(filter, reverse || false);
64 request.onsuccess = function(event) {
65 if (!request.done) {
66 messages.push(request.result);
67 request.continue();
68 return;
69 }
71 window.setTimeout(callback.bind(null, messages), 0);
72 }
73 }
75 function deleteAllMessages() {
76 getAllMessages(function deleteAll(messages) {
77 let message = messages.shift();
78 if (!message) {
79 ok(true, "all messages deleted");
80 tasks.next();
81 return;
82 }
84 let request = manager.delete(message.id);
85 request.onsuccess = deleteAll.bind(null, messages);
86 request.onerror = function(event) {
87 ok(false, "failed to delete all messages");
88 tasks.finish();
89 }
90 });
91 }
93 function sendMessage(to, body) {
94 manager.onsent = function() {
95 manager.onsent = null;
96 tasks.next();
97 };
98 let request = manager.send(to, body);
99 request.onerror = tasks.finish.bind(tasks);
100 }
102 function receiveMessage(from, body) {
103 manager.onreceived = function() {
104 manager.onreceived = null;
105 tasks.next();
106 };
107 sendSmsToEmulator(from, body, function(success) {
108 if (!success) {
109 tasks.finish();
110 }
111 });
112 }
114 function getAllThreads(callback) {
115 let threads = [];
117 let cursor = manager.getThreads();
118 ok(cursor instanceof DOMCursor,
119 "cursor is instanceof " + cursor.constructor);
121 cursor.onsuccess = function(event) {
122 if (!cursor.done) {
123 threads.push(cursor.result);
124 cursor.continue();
125 return;
126 }
128 window.setTimeout(callback.bind(null, threads), 0);
129 };
130 }
132 function checkThread(bodies, lastBody, unreadCount, participants,
133 thread, callback) {
134 log("Validating MozMobileMessageThread attributes " +
135 JSON.stringify([bodies, lastBody, unreadCount, participants]));
137 ok(thread, "current thread should be valid.");
139 ok(thread.id, "thread id", "thread.id");
140 log("Got thread " + thread.id);
142 if (lastBody != null) {
143 is(thread.body, lastBody, "thread.body");
144 }
146 is(thread.unreadCount, unreadCount, "thread.unreadCount");
148 ok(Array.isArray(thread.participants), "thread.participants is array");
149 is(thread.participants.length, participants.length,
150 "thread.participants.length");
151 for (let i = 0; i < participants.length; i++) {
152 is(thread.participants[i], participants[i],
153 "thread.participants[" + i + "]");
154 }
156 // Check whether the thread does contain all the messages it supposed to have.
157 let filter = new MozSmsFilter;
158 filter.threadId = thread.id;
159 getAllMessages(function(messages) {
160 is(messages.length, bodies.length, "messages.length and bodies.length");
162 for (let message of messages) {
163 let index = bodies.indexOf(message.body);
164 ok(index >= 0, "message.body '" + message.body +
165 "' should be found in bodies array.");
166 bodies.splice(index, 1);
167 }
169 is(bodies.length, 0, "bodies array length");
171 window.setTimeout(callback, 0);
172 }, filter, false);
173 }
175 tasks.push(deleteAllMessages);
177 tasks.push(getAllThreads.bind(null, function(threads) {
178 is(threads.length, 0, "Empty thread list at beginning.");
179 tasks.next();
180 }));
182 // Populate MobileMessageDB with messages.
183 let checkFuncs = [];
185 // [Thread 1]
186 // One message only, body = "thread 1";
187 // All sent message, unreadCount = 0;
188 // One participant only, participants = ["5555211001"].
189 tasks.push(sendMessage.bind(null, "5555211001", "thread 1"));
190 checkFuncs.push(checkThread.bind(null, ["thread 1"],
191 "thread 1", 0, ["5555211001"]));
193 // [Thread 2]
194 // Two messages, body = "thread 2-2";
195 // All sent message, unreadCount = 0;
196 // One participant with two aliased addresses, participants = ["5555211002"].
197 tasks.push(sendMessage.bind(null, "5555211002", "thread 2-1"));
198 tasks.push(sendMessage.bind(null, "+15555211002", "thread 2-2"));
199 checkFuncs.push(checkThread.bind(null, ["thread 2-1", "thread 2-2"],
200 "thread 2-2", 0, ["5555211002"]));
202 // [Thread 3]
203 // Two messages, body = "thread 3-2";
204 // All sent message, unreadCount = 0;
205 // One participant with two aliased addresses, participants = ["+15555211003"].
206 tasks.push(sendMessage.bind(null, "+15555211003", "thread 3-1"));
207 tasks.push(sendMessage.bind(null, "5555211003", "thread 3-2"));
208 checkFuncs.push(checkThread.bind(null, ["thread 3-1", "thread 3-2"],
209 "thread 3-2", 0, ["+15555211003"]));
211 // [Thread 4]
212 // One message only, body = "thread 4";
213 // All received message, unreadCount = 1;
214 // One participant only, participants = ["5555211004"].
215 tasks.push(receiveMessage.bind(null, "5555211004", "thread 4"));
216 checkFuncs.push(checkThread.bind(null, ["thread 4"],
217 "thread 4", 1, ["5555211004"]));
219 // [Thread 5]
220 //
221 // Thread body should be set to text body of the last message in this
222 // thread. However due to BUG 840051, we're having SMSC time as message
223 // timestamp and SMSC time resolution is 1 second. So it's likely that the two
224 // messages have the same timestamp and we just can't tell which is the later
225 // one.
226 //
227 // All received message, unreadCount = 2;
228 // One participant with two aliased addresses, participants = ["5555211005"].
229 tasks.push(receiveMessage.bind(null, "5555211005", "thread 5-1"));
230 tasks.push(receiveMessage.bind(null, "+15555211005", "thread 5-2"));
231 checkFuncs.push(checkThread.bind(null, ["thread 5-1", "thread 5-2"],
232 null, 2, ["5555211005"]));
234 // [Thread 6]
235 //
236 // Thread body should be set to text body of the last message in this
237 // thread. However due to BUG 840051, we're having SMSC time as message
238 // timestamp and SMSC time resolution is 1 second. So it's likely that the two
239 // messages have the same timestamp and we just can't tell which is the later
240 // one.
241 //
242 // All received message, unreadCount = 2;
243 // One participant with two aliased addresses, participants = ["+15555211006"].
244 tasks.push(receiveMessage.bind(null, "+15555211006", "thread 6-1"));
245 tasks.push(receiveMessage.bind(null, "5555211006", "thread 6-2"));
246 checkFuncs.push(checkThread.bind(null, ["thread 6-1", "thread 6-2"],
247 null, 2, ["+15555211006"]));
249 // [Thread 7]
250 //
251 // Thread body should be set to text body of the last message in this
252 // thread. However due to BUG 840051, there might be time difference between
253 // SMSC and device time. So the result of comparing the timestamps of sent and
254 // received message may not follow the order of requests and may result in
255 // UNEXPECTED-FAIL in following tests.
256 //
257 // Two received message, unreadCount = 2;
258 // One participant with two aliased addresses, participants = ["5555211007"].
259 tasks.push(sendMessage.bind(null, "5555211007", "thread 7-1"));
260 tasks.push(sendMessage.bind(null, "+15555211007", "thread 7-2"));
261 tasks.push(receiveMessage.bind(null, "5555211007", "thread 7-3"));
262 tasks.push(receiveMessage.bind(null, "+15555211007", "thread 7-4"));
263 checkFuncs.push(checkThread.bind(null, ["thread 7-1", "thread 7-2",
264 "thread 7-3", "thread 7-4"],
265 null, 2, ["5555211007"]));
267 // [Thread 8]
268 //
269 // Thread body should be set to text body of the last message in this
270 // thread. However due to BUG 840051, there might be time difference between
271 // SMSC and device time. So the result of comparing the timestamps of sent and
272 // received message may not follow the order of requests and may result in
273 // UNEXPECTED-FAIL in following tests.
274 //
275 // Two received message, unreadCount = 2;
276 // One participant with two aliased addresses, participants = ["5555211008"].
277 tasks.push(receiveMessage.bind(null, "5555211008", "thread 8-1"));
278 tasks.push(receiveMessage.bind(null, "+15555211008", "thread 8-2"));
279 tasks.push(sendMessage.bind(null, "5555211008", "thread 8-3"));
280 tasks.push(sendMessage.bind(null, "+15555211008", "thread 8-4"));
281 checkFuncs.push(checkThread.bind(null, ["thread 8-1", "thread 8-2",
282 "thread 8-3", "thread 8-4"],
283 null, 2, ["5555211008"]));
285 // [Thread 9]
286 // Three sent message, unreadCount = 0;
287 // One participant with three aliased addresses, participants = ["+15555211009"].
288 tasks.push(sendMessage.bind(null, "+15555211009", "thread 9-1"));
289 tasks.push(sendMessage.bind(null, "01115555211009", "thread 9-2"));
290 tasks.push(sendMessage.bind(null, "5555211009", "thread 9-3"));
291 checkFuncs.push(checkThread.bind(null, ["thread 9-1", "thread 9-2",
292 "thread 9-3"],
293 "thread 9-3", 0, ["+15555211009"]));
295 // [Thread 10]
296 // Three sent message, unreadCount = 0;
297 // One participant with three aliased addresses, participants = ["+15555211010"].
298 tasks.push(sendMessage.bind(null, "+15555211010", "thread 10-1"));
299 tasks.push(sendMessage.bind(null, "5555211010", "thread 10-2"));
300 tasks.push(sendMessage.bind(null, "01115555211010", "thread 10-3"));
301 checkFuncs.push(checkThread.bind(null, ["thread 10-1", "thread 10-2",
302 "thread 10-3"],
303 "thread 10-3", 0, ["+15555211010"]));
305 // [Thread 11]
306 // Three sent message, unreadCount = 0;
307 // One participant with three aliased addresses, participants = ["01115555211011"].
308 tasks.push(sendMessage.bind(null, "01115555211011", "thread 11-1"));
309 tasks.push(sendMessage.bind(null, "5555211011", "thread 11-2"));
310 tasks.push(sendMessage.bind(null, "+15555211011", "thread 11-3"));
311 checkFuncs.push(checkThread.bind(null, ["thread 11-1", "thread 11-2",
312 "thread 11-3"],
313 "thread 11-3", 0, ["01115555211011"]));
315 // [Thread 12]
316 // Three sent message, unreadCount = 0;
317 // One participant with three aliased addresses, participants = ["01115555211012"].
318 tasks.push(sendMessage.bind(null, "01115555211012", "thread 12-1"));
319 tasks.push(sendMessage.bind(null, "+15555211012", "thread 12-2"));
320 tasks.push(sendMessage.bind(null, "5555211012", "thread 12-3"));
321 checkFuncs.push(checkThread.bind(null, ["thread 12-1", "thread 12-2",
322 "thread 12-3"],
323 "thread 12-3", 0, ["01115555211012"]));
325 // [Thread 13]
326 // Three sent message, unreadCount = 0;
327 // One participant with three aliased addresses, participants = ["5555211013"].
328 tasks.push(sendMessage.bind(null, "5555211013", "thread 13-1"));
329 tasks.push(sendMessage.bind(null, "+15555211013", "thread 13-2"));
330 tasks.push(sendMessage.bind(null, "01115555211013", "thread 13-3"));
331 checkFuncs.push(checkThread.bind(null, ["thread 13-1", "thread 13-2",
332 "thread 13-3"],
333 "thread 13-3", 0, ["5555211013"]));
335 // [Thread 14]
336 // Three sent message, unreadCount = 0;
337 // One participant with three aliased addresses, participants = ["5555211014"].
338 tasks.push(sendMessage.bind(null, "5555211014", "thread 14-1"));
339 tasks.push(sendMessage.bind(null, "01115555211014", "thread 14-2"));
340 tasks.push(sendMessage.bind(null, "+15555211014", "thread 14-3"));
341 checkFuncs.push(checkThread.bind(null, ["thread 14-1", "thread 14-2",
342 "thread 14-3"],
343 "thread 14-3", 0, ["5555211014"]));
345 //[Thread 15]
346 //Three sent message, unreadCount = 0;
347 //One participant but might be merged to 555211015, participants = ["5555211015"].
348 tasks.push(sendMessage.bind(null, "5555211015", "thread 15-1"));
349 checkFuncs.push(checkThread.bind(null, ["thread 15-1"],
350 "thread 15-1", 0, ["5555211015"]));
352 //[Thread 16]
353 //Three sent message, unreadCount = 0;
354 //One participant but might be merged to 5555211015, participants = ["555211015"].
355 tasks.push(sendMessage.bind(null, "555211015", "thread 16-1"));
356 checkFuncs.push(checkThread.bind(null, ["thread 16-1"],
357 "thread 16-1", 0, ["555211015"]));
359 //[Thread 17]
360 //Three sent message, unreadCount = 0;
361 //One participant with two aliased addresses, participants = ["555211017"].
362 tasks.push(sendMessage.bind(null, "+5511555211017", "thread 17-1"));
363 tasks.push(sendMessage.bind(null, "555211017", "thread 17-2"));
364 checkFuncs.push(checkThread.bind(null, ["thread 17-1", "thread 17-2"],
365 "thread 17-2", 0, ["+5511555211017"]));
367 //[Thread 18]
368 //Three sent message, unreadCount = 0;
369 //One participant with two aliased addresses, participants = ["555211018"].
370 tasks.push(sendMessage.bind(null, "555211018", "thread 18-1"));
371 tasks.push(sendMessage.bind(null, "+5511555211018", "thread 18-2"));
372 checkFuncs.push(checkThread.bind(null, ["thread 18-1", "thread 18-2"],
373 "thread 18-2", 0, ["555211018"]));
375 // Check threads.
376 tasks.push(getAllThreads.bind(null, function(threads) {
377 is(threads.length, checkFuncs.length, "number of threads got");
379 // Reverse threads as we iterate over them in reverse order
380 threads.reverse();
382 (function callback() {
383 if (!threads.length) {
384 tasks.next();
385 return;
386 }
388 checkFuncs.shift()(threads.shift(), callback);
389 })();
390 }));
392 tasks.push(deleteAllMessages);
394 tasks.push(getAllThreads.bind(null, function(threads) {
395 is(threads.length, 0, "Empty thread list at the end.");
396 tasks.next();
397 }));
399 // WARNING: All tasks should be pushed before this!!!
400 tasks.push(function cleanUp() {
401 if (pendingEmulatorCmdCount) {
402 window.setTimeout(cleanUp, 100);
403 return;
404 }
406 SpecialPowers.removePermission("sms", document);
407 SpecialPowers.clearUserPref("dom.sms.enabled");
408 finish();
409 });
411 tasks.run();