diff -r 000000000000 -r 6474c204b198 dom/mobilemessage/tests/marionette/test_getthreads.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dom/mobilemessage/tests/marionette/test_getthreads.js Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,411 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +MARIONETTE_TIMEOUT = 40000; + +SpecialPowers.addPermission("sms", true, document); +SpecialPowers.setBoolPref("dom.sms.enabled", true); + +let manager = window.navigator.mozMobileMessage; +ok(manager instanceof MozMobileMessageManager, + "manager is instance of " + manager.constructor); + +let pendingEmulatorCmdCount = 0; +function sendSmsToEmulator(from, text, callback) { + ++pendingEmulatorCmdCount; + + let cmd = "sms send " + from + " " + text; + runEmulatorCmd(cmd, function(result) { + --pendingEmulatorCmdCount; + + callback(result[0] == "OK"); + }); +} + +let tasks = { + // List of test fuctions. Each of them should call |tasks.next()| when + // completed or |tasks.finish()| to jump to the last one. + _tasks: [], + _nextTaskIndex: 0, + + push: function(func) { + this._tasks.push(func); + }, + + next: function() { + let index = this._nextTaskIndex++; + let task = this._tasks[index]; + try { + task.apply(null, Array.slice(arguments)); + } catch (ex) { + ok(false, "test task[" + index + "] throws: " + ex); + // Run last task as clean up if possible. + if (index != this._tasks.length - 1) { + this.finish(); + } + } + }, + + finish: function() { + this._tasks[this._tasks.length - 1](); + }, + + run: function() { + this.next(); + } +}; + +function getAllMessages(callback, filter, reverse) { + if (!filter) { + filter = new MozSmsFilter; + } + let messages = []; + let request = manager.getMessages(filter, reverse || false); + request.onsuccess = function(event) { + if (!request.done) { + messages.push(request.result); + request.continue(); + return; + } + + window.setTimeout(callback.bind(null, messages), 0); + } +} + +function deleteAllMessages() { + getAllMessages(function deleteAll(messages) { + let message = messages.shift(); + if (!message) { + ok(true, "all messages deleted"); + tasks.next(); + return; + } + + let request = manager.delete(message.id); + request.onsuccess = deleteAll.bind(null, messages); + request.onerror = function(event) { + ok(false, "failed to delete all messages"); + tasks.finish(); + } + }); +} + +function sendMessage(to, body) { + manager.onsent = function() { + manager.onsent = null; + tasks.next(); + }; + let request = manager.send(to, body); + request.onerror = tasks.finish.bind(tasks); +} + +function receiveMessage(from, body) { + manager.onreceived = function() { + manager.onreceived = null; + tasks.next(); + }; + sendSmsToEmulator(from, body, function(success) { + if (!success) { + tasks.finish(); + } + }); +} + +function getAllThreads(callback) { + let threads = []; + + let cursor = manager.getThreads(); + ok(cursor instanceof DOMCursor, + "cursor is instanceof " + cursor.constructor); + + cursor.onsuccess = function(event) { + if (!cursor.done) { + threads.push(cursor.result); + cursor.continue(); + return; + } + + window.setTimeout(callback.bind(null, threads), 0); + }; +} + +function checkThread(bodies, lastBody, unreadCount, participants, + thread, callback) { + log("Validating MozMobileMessageThread attributes " + + JSON.stringify([bodies, lastBody, unreadCount, participants])); + + ok(thread, "current thread should be valid."); + + ok(thread.id, "thread id", "thread.id"); + log("Got thread " + thread.id); + + if (lastBody != null) { + is(thread.body, lastBody, "thread.body"); + } + + is(thread.unreadCount, unreadCount, "thread.unreadCount"); + + ok(Array.isArray(thread.participants), "thread.participants is array"); + is(thread.participants.length, participants.length, + "thread.participants.length"); + for (let i = 0; i < participants.length; i++) { + is(thread.participants[i], participants[i], + "thread.participants[" + i + "]"); + } + + // Check whether the thread does contain all the messages it supposed to have. + let filter = new MozSmsFilter; + filter.threadId = thread.id; + getAllMessages(function(messages) { + is(messages.length, bodies.length, "messages.length and bodies.length"); + + for (let message of messages) { + let index = bodies.indexOf(message.body); + ok(index >= 0, "message.body '" + message.body + + "' should be found in bodies array."); + bodies.splice(index, 1); + } + + is(bodies.length, 0, "bodies array length"); + + window.setTimeout(callback, 0); + }, filter, false); +} + +tasks.push(deleteAllMessages); + +tasks.push(getAllThreads.bind(null, function(threads) { + is(threads.length, 0, "Empty thread list at beginning."); + tasks.next(); +})); + +// Populate MobileMessageDB with messages. +let checkFuncs = []; + +// [Thread 1] +// One message only, body = "thread 1"; +// All sent message, unreadCount = 0; +// One participant only, participants = ["5555211001"]. +tasks.push(sendMessage.bind(null, "5555211001", "thread 1")); +checkFuncs.push(checkThread.bind(null, ["thread 1"], + "thread 1", 0, ["5555211001"])); + +// [Thread 2] +// Two messages, body = "thread 2-2"; +// All sent message, unreadCount = 0; +// One participant with two aliased addresses, participants = ["5555211002"]. +tasks.push(sendMessage.bind(null, "5555211002", "thread 2-1")); +tasks.push(sendMessage.bind(null, "+15555211002", "thread 2-2")); +checkFuncs.push(checkThread.bind(null, ["thread 2-1", "thread 2-2"], + "thread 2-2", 0, ["5555211002"])); + +// [Thread 3] +// Two messages, body = "thread 3-2"; +// All sent message, unreadCount = 0; +// One participant with two aliased addresses, participants = ["+15555211003"]. +tasks.push(sendMessage.bind(null, "+15555211003", "thread 3-1")); +tasks.push(sendMessage.bind(null, "5555211003", "thread 3-2")); +checkFuncs.push(checkThread.bind(null, ["thread 3-1", "thread 3-2"], + "thread 3-2", 0, ["+15555211003"])); + +// [Thread 4] +// One message only, body = "thread 4"; +// All received message, unreadCount = 1; +// One participant only, participants = ["5555211004"]. +tasks.push(receiveMessage.bind(null, "5555211004", "thread 4")); +checkFuncs.push(checkThread.bind(null, ["thread 4"], + "thread 4", 1, ["5555211004"])); + +// [Thread 5] +// +// Thread body should be set to text body of the last message in this +// thread. However due to BUG 840051, we're having SMSC time as message +// timestamp and SMSC time resolution is 1 second. So it's likely that the two +// messages have the same timestamp and we just can't tell which is the later +// one. +// +// All received message, unreadCount = 2; +// One participant with two aliased addresses, participants = ["5555211005"]. +tasks.push(receiveMessage.bind(null, "5555211005", "thread 5-1")); +tasks.push(receiveMessage.bind(null, "+15555211005", "thread 5-2")); +checkFuncs.push(checkThread.bind(null, ["thread 5-1", "thread 5-2"], + null, 2, ["5555211005"])); + +// [Thread 6] +// +// Thread body should be set to text body of the last message in this +// thread. However due to BUG 840051, we're having SMSC time as message +// timestamp and SMSC time resolution is 1 second. So it's likely that the two +// messages have the same timestamp and we just can't tell which is the later +// one. +// +// All received message, unreadCount = 2; +// One participant with two aliased addresses, participants = ["+15555211006"]. +tasks.push(receiveMessage.bind(null, "+15555211006", "thread 6-1")); +tasks.push(receiveMessage.bind(null, "5555211006", "thread 6-2")); +checkFuncs.push(checkThread.bind(null, ["thread 6-1", "thread 6-2"], + null, 2, ["+15555211006"])); + +// [Thread 7] +// +// Thread body should be set to text body of the last message in this +// thread. However due to BUG 840051, there might be time difference between +// SMSC and device time. So the result of comparing the timestamps of sent and +// received message may not follow the order of requests and may result in +// UNEXPECTED-FAIL in following tests. +// +// Two received message, unreadCount = 2; +// One participant with two aliased addresses, participants = ["5555211007"]. +tasks.push(sendMessage.bind(null, "5555211007", "thread 7-1")); +tasks.push(sendMessage.bind(null, "+15555211007", "thread 7-2")); +tasks.push(receiveMessage.bind(null, "5555211007", "thread 7-3")); +tasks.push(receiveMessage.bind(null, "+15555211007", "thread 7-4")); +checkFuncs.push(checkThread.bind(null, ["thread 7-1", "thread 7-2", + "thread 7-3", "thread 7-4"], + null, 2, ["5555211007"])); + +// [Thread 8] +// +// Thread body should be set to text body of the last message in this +// thread. However due to BUG 840051, there might be time difference between +// SMSC and device time. So the result of comparing the timestamps of sent and +// received message may not follow the order of requests and may result in +// UNEXPECTED-FAIL in following tests. +// +// Two received message, unreadCount = 2; +// One participant with two aliased addresses, participants = ["5555211008"]. +tasks.push(receiveMessage.bind(null, "5555211008", "thread 8-1")); +tasks.push(receiveMessage.bind(null, "+15555211008", "thread 8-2")); +tasks.push(sendMessage.bind(null, "5555211008", "thread 8-3")); +tasks.push(sendMessage.bind(null, "+15555211008", "thread 8-4")); +checkFuncs.push(checkThread.bind(null, ["thread 8-1", "thread 8-2", + "thread 8-3", "thread 8-4"], + null, 2, ["5555211008"])); + +// [Thread 9] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["+15555211009"]. +tasks.push(sendMessage.bind(null, "+15555211009", "thread 9-1")); +tasks.push(sendMessage.bind(null, "01115555211009", "thread 9-2")); +tasks.push(sendMessage.bind(null, "5555211009", "thread 9-3")); +checkFuncs.push(checkThread.bind(null, ["thread 9-1", "thread 9-2", + "thread 9-3"], + "thread 9-3", 0, ["+15555211009"])); + +// [Thread 10] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["+15555211010"]. +tasks.push(sendMessage.bind(null, "+15555211010", "thread 10-1")); +tasks.push(sendMessage.bind(null, "5555211010", "thread 10-2")); +tasks.push(sendMessage.bind(null, "01115555211010", "thread 10-3")); +checkFuncs.push(checkThread.bind(null, ["thread 10-1", "thread 10-2", + "thread 10-3"], + "thread 10-3", 0, ["+15555211010"])); + +// [Thread 11] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["01115555211011"]. +tasks.push(sendMessage.bind(null, "01115555211011", "thread 11-1")); +tasks.push(sendMessage.bind(null, "5555211011", "thread 11-2")); +tasks.push(sendMessage.bind(null, "+15555211011", "thread 11-3")); +checkFuncs.push(checkThread.bind(null, ["thread 11-1", "thread 11-2", + "thread 11-3"], + "thread 11-3", 0, ["01115555211011"])); + +// [Thread 12] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["01115555211012"]. +tasks.push(sendMessage.bind(null, "01115555211012", "thread 12-1")); +tasks.push(sendMessage.bind(null, "+15555211012", "thread 12-2")); +tasks.push(sendMessage.bind(null, "5555211012", "thread 12-3")); +checkFuncs.push(checkThread.bind(null, ["thread 12-1", "thread 12-2", + "thread 12-3"], + "thread 12-3", 0, ["01115555211012"])); + +// [Thread 13] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["5555211013"]. +tasks.push(sendMessage.bind(null, "5555211013", "thread 13-1")); +tasks.push(sendMessage.bind(null, "+15555211013", "thread 13-2")); +tasks.push(sendMessage.bind(null, "01115555211013", "thread 13-3")); +checkFuncs.push(checkThread.bind(null, ["thread 13-1", "thread 13-2", + "thread 13-3"], + "thread 13-3", 0, ["5555211013"])); + +// [Thread 14] +// Three sent message, unreadCount = 0; +// One participant with three aliased addresses, participants = ["5555211014"]. +tasks.push(sendMessage.bind(null, "5555211014", "thread 14-1")); +tasks.push(sendMessage.bind(null, "01115555211014", "thread 14-2")); +tasks.push(sendMessage.bind(null, "+15555211014", "thread 14-3")); +checkFuncs.push(checkThread.bind(null, ["thread 14-1", "thread 14-2", + "thread 14-3"], + "thread 14-3", 0, ["5555211014"])); + +//[Thread 15] +//Three sent message, unreadCount = 0; +//One participant but might be merged to 555211015, participants = ["5555211015"]. +tasks.push(sendMessage.bind(null, "5555211015", "thread 15-1")); +checkFuncs.push(checkThread.bind(null, ["thread 15-1"], + "thread 15-1", 0, ["5555211015"])); + +//[Thread 16] +//Three sent message, unreadCount = 0; +//One participant but might be merged to 5555211015, participants = ["555211015"]. +tasks.push(sendMessage.bind(null, "555211015", "thread 16-1")); +checkFuncs.push(checkThread.bind(null, ["thread 16-1"], + "thread 16-1", 0, ["555211015"])); + +//[Thread 17] +//Three sent message, unreadCount = 0; +//One participant with two aliased addresses, participants = ["555211017"]. +tasks.push(sendMessage.bind(null, "+5511555211017", "thread 17-1")); +tasks.push(sendMessage.bind(null, "555211017", "thread 17-2")); +checkFuncs.push(checkThread.bind(null, ["thread 17-1", "thread 17-2"], + "thread 17-2", 0, ["+5511555211017"])); + +//[Thread 18] +//Three sent message, unreadCount = 0; +//One participant with two aliased addresses, participants = ["555211018"]. +tasks.push(sendMessage.bind(null, "555211018", "thread 18-1")); +tasks.push(sendMessage.bind(null, "+5511555211018", "thread 18-2")); +checkFuncs.push(checkThread.bind(null, ["thread 18-1", "thread 18-2"], + "thread 18-2", 0, ["555211018"])); + +// Check threads. +tasks.push(getAllThreads.bind(null, function(threads) { + is(threads.length, checkFuncs.length, "number of threads got"); + + // Reverse threads as we iterate over them in reverse order + threads.reverse(); + + (function callback() { + if (!threads.length) { + tasks.next(); + return; + } + + checkFuncs.shift()(threads.shift(), callback); + })(); +})); + +tasks.push(deleteAllMessages); + +tasks.push(getAllThreads.bind(null, function(threads) { + is(threads.length, 0, "Empty thread list at the end."); + tasks.next(); +})); + +// WARNING: All tasks should be pushed before this!!! +tasks.push(function cleanUp() { + if (pendingEmulatorCmdCount) { + window.setTimeout(cleanUp, 100); + return; + } + + SpecialPowers.removePermission("sms", document); + SpecialPowers.clearUserPref("dom.sms.enabled"); + finish(); +}); + +tasks.run();