|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 * http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 MARIONETTE_TIMEOUT = 40000; |
|
5 |
|
6 SpecialPowers.addPermission("sms", true, document); |
|
7 SpecialPowers.setBoolPref("dom.sms.enabled", true); |
|
8 |
|
9 let manager = window.navigator.mozMobileMessage; |
|
10 ok(manager instanceof MozMobileMessageManager, |
|
11 "manager is instance of " + manager.constructor); |
|
12 |
|
13 let pendingEmulatorCmdCount = 0; |
|
14 function sendSmsToEmulator(from, text, callback) { |
|
15 ++pendingEmulatorCmdCount; |
|
16 |
|
17 let cmd = "sms send " + from + " " + text; |
|
18 runEmulatorCmd(cmd, function(result) { |
|
19 --pendingEmulatorCmdCount; |
|
20 |
|
21 callback(result[0] == "OK"); |
|
22 }); |
|
23 } |
|
24 |
|
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, |
|
30 |
|
31 push: function(func) { |
|
32 this._tasks.push(func); |
|
33 }, |
|
34 |
|
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 }, |
|
48 |
|
49 finish: function() { |
|
50 this._tasks[this._tasks.length - 1](); |
|
51 }, |
|
52 |
|
53 run: function() { |
|
54 this.next(); |
|
55 } |
|
56 }; |
|
57 |
|
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 } |
|
70 |
|
71 window.setTimeout(callback.bind(null, messages), 0); |
|
72 } |
|
73 } |
|
74 |
|
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 } |
|
83 |
|
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 } |
|
92 |
|
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 } |
|
101 |
|
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 } |
|
113 |
|
114 function getAllThreads(callback) { |
|
115 let threads = []; |
|
116 |
|
117 let cursor = manager.getThreads(); |
|
118 ok(cursor instanceof DOMCursor, |
|
119 "cursor is instanceof " + cursor.constructor); |
|
120 |
|
121 cursor.onsuccess = function(event) { |
|
122 if (!cursor.done) { |
|
123 threads.push(cursor.result); |
|
124 cursor.continue(); |
|
125 return; |
|
126 } |
|
127 |
|
128 window.setTimeout(callback.bind(null, threads), 0); |
|
129 }; |
|
130 } |
|
131 |
|
132 function checkThread(bodies, lastBody, unreadCount, participants, |
|
133 thread, callback) { |
|
134 log("Validating MozMobileMessageThread attributes " + |
|
135 JSON.stringify([bodies, lastBody, unreadCount, participants])); |
|
136 |
|
137 ok(thread, "current thread should be valid."); |
|
138 |
|
139 ok(thread.id, "thread id", "thread.id"); |
|
140 log("Got thread " + thread.id); |
|
141 |
|
142 if (lastBody != null) { |
|
143 is(thread.body, lastBody, "thread.body"); |
|
144 } |
|
145 |
|
146 is(thread.unreadCount, unreadCount, "thread.unreadCount"); |
|
147 |
|
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 } |
|
155 |
|
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"); |
|
161 |
|
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 } |
|
168 |
|
169 is(bodies.length, 0, "bodies array length"); |
|
170 |
|
171 window.setTimeout(callback, 0); |
|
172 }, filter, false); |
|
173 } |
|
174 |
|
175 tasks.push(deleteAllMessages); |
|
176 |
|
177 tasks.push(getAllThreads.bind(null, function(threads) { |
|
178 is(threads.length, 0, "Empty thread list at beginning."); |
|
179 tasks.next(); |
|
180 })); |
|
181 |
|
182 // Populate MobileMessageDB with messages. |
|
183 let checkFuncs = []; |
|
184 |
|
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"])); |
|
192 |
|
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"])); |
|
201 |
|
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"])); |
|
210 |
|
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"])); |
|
218 |
|
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"])); |
|
233 |
|
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"])); |
|
248 |
|
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"])); |
|
266 |
|
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"])); |
|
284 |
|
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"])); |
|
294 |
|
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"])); |
|
304 |
|
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"])); |
|
314 |
|
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"])); |
|
324 |
|
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"])); |
|
334 |
|
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"])); |
|
344 |
|
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"])); |
|
351 |
|
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"])); |
|
358 |
|
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"])); |
|
366 |
|
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"])); |
|
374 |
|
375 // Check threads. |
|
376 tasks.push(getAllThreads.bind(null, function(threads) { |
|
377 is(threads.length, checkFuncs.length, "number of threads got"); |
|
378 |
|
379 // Reverse threads as we iterate over them in reverse order |
|
380 threads.reverse(); |
|
381 |
|
382 (function callback() { |
|
383 if (!threads.length) { |
|
384 tasks.next(); |
|
385 return; |
|
386 } |
|
387 |
|
388 checkFuncs.shift()(threads.shift(), callback); |
|
389 })(); |
|
390 })); |
|
391 |
|
392 tasks.push(deleteAllMessages); |
|
393 |
|
394 tasks.push(getAllThreads.bind(null, function(threads) { |
|
395 is(threads.length, 0, "Empty thread list at the end."); |
|
396 tasks.next(); |
|
397 })); |
|
398 |
|
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 } |
|
405 |
|
406 SpecialPowers.removePermission("sms", document); |
|
407 SpecialPowers.clearUserPref("dom.sms.enabled"); |
|
408 finish(); |
|
409 }); |
|
410 |
|
411 tasks.run(); |