Bug 736708 - 3/3: test cases. r=gene
authorVicamo Yang <vyang@mozilla.com>
Wed, 20 Nov 2013 03:46:19 +0800
changeset 156375 62a9868126428d86ef50225dd734755ee197ae94
parent 156374 ed0ffb6a9c8f9b74606fab802651499811d6719a
child 156376 35090a27e0c478d5bcaee0bfc4ff56817570edd7
push id25677
push userryanvm@gmail.com
push dateWed, 20 Nov 2013 01:40:17 +0000
treeherdermozilla-central@0587548f1428 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgene
bugs736708
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 736708 - 3/3: test cases. r=gene
dom/mobilemessage/tests/marionette/head.js
dom/mobilemessage/tests/marionette/manifest.ini
dom/mobilemessage/tests/marionette/test_replace_short_message_type.js
--- a/dom/mobilemessage/tests/marionette/head.js
+++ b/dom/mobilemessage/tests/marionette/head.js
@@ -191,17 +191,17 @@ function getAllThreads() {
  * @aThreadId a numeric value identifying the target thread.
  *
  * @return A deferred promise.
  */
 function getThreadById(aThreadId) {
   return getAllThreads()
     .then(function(aThreads) {
       for (let thread of aThreads) {
-        if (thread.id == aThreadId) {
+        if (thread.id === aThreadId) {
           return thread;
         }
       }
       throw undefined;
     });
 }
 
 /* Delete messages specified from database.
@@ -262,16 +262,80 @@ function deleteMessages(aMessages) {
  *   event -- a DOMEvent.
  *
  * @return A deferred promise.
  */
 function deleteAllMessages() {
   return getAllMessages().then(deleteMessages);
 }
 
+let pendingEmulatorCmdCount = 0;
+
+/* Send emulator command with safe guard.
+ *
+ * We should only call |finish()| after all emulator command transactions
+ * end, so here comes with the pending counter.  Resolve when the emulator
+ * gives positive response, and reject otherwise.
+ *
+ * Forfill params:
+ *   result -- an array of emulator response lines.
+ *
+ * Reject params:
+ *   result -- an array of emulator response lines.
+ *
+ * @return A deferred promise.
+ */
+function runEmulatorCmdSafe(aCommand) {
+  let deferred = Promise.defer();
+
+  ++pendingEmulatorCmdCount;
+  runEmulatorCmd(aCommand, function(aResult) {
+    --pendingEmulatorCmdCount;
+
+    ok(true, "Emulator response: " + JSON.stringify(aResult));
+    if (Array.isArray(aResult) && aResult[0] === "OK") {
+      deferred.resolve(aResult);
+    } else {
+      deferred.reject(aResult);
+    }
+  });
+
+  return deferred.promise;
+}
+
+/* Send simple text SMS to emulator.
+ *
+ * Forfill params:
+ *   result -- an array of emulator response lines.
+ *
+ * Reject params:
+ *   result -- an array of emulator response lines.
+ *
+ * @return A deferred promise.
+ */
+function sendTextSmsToEmulator(aFrom, aText) {
+  let command = "sms send " + aFrom + " " + aText;
+  return runEmulatorCmdSafe(command);
+}
+
+/* Send raw SMS TPDU to emulator.
+ *
+ * Forfill params:
+ *   result -- an array of emulator response lines.
+ *
+ * Reject params:
+ *   result -- an array of emulator response lines.
+ *
+ * @return A deferred promise.
+ */
+function sendRawSmsToEmulator(aPdu) {
+  let command = "sms pdu " + aPdu;
+  return runEmulatorCmdSafe(command);
+}
+
 /* Create a new array of id attribute of input messages.
  *
  * @param aMessages an array of {Sms,Mms}Message instances.
  *
  * @return an array of numeric values.
  */
 function messagesToIds(aMessages) {
   let ids = [];
@@ -279,23 +343,30 @@ function messagesToIds(aMessages) {
     ids.push(message.id);
   }
   return ids;
 }
 
 /* Flush permission settings and call |finish()|.
  */
 function cleanUp() {
-  SpecialPowers.flushPermissions(function() {
-    // Use ok here so that we have at least one test run.
-    ok(true, "permissions flushed");
+  waitFor(function() {
+    SpecialPowers.flushPermissions(function() {
+      // Use ok here so that we have at least one test run.
+      ok(true, "permissions flushed");
 
-    finish();
+      finish();
+    });
+  }, function() {
+    return pendingEmulatorCmdCount === 0;
   });
 }
 
 function startTestCommon(aTestCaseMain) {
   ensureMobileMessage()
     .then(deleteAllMessages)
     .then(aTestCaseMain)
     .then(deleteAllMessages)
-    .then(cleanUp, cleanUp);
+    .then(cleanUp, function() {
+      ok(false, 'promise rejects during test.');
+      cleanUp();
+    });
 }
--- a/dom/mobilemessage/tests/marionette/manifest.ini
+++ b/dom/mobilemessage/tests/marionette/manifest.ini
@@ -35,8 +35,9 @@ qemu = true
 [test_phone_number_normalization.js]
 [test_invalid_address.js]
 [test_mmsmessage_attachments.js]
 [test_getthreads.js]
 [test_smsc_address.js]
 [test_dsds_default_service_id.js]
 [test_thread_subject.js]
 [test_mmdb_setmessagedeliverybyid_sms.js]
+[test_replace_short_message_type.js]
new file mode 100644
--- /dev/null
+++ b/dom/mobilemessage/tests/marionette/test_replace_short_message_type.js
@@ -0,0 +1,121 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+const PDU_SMSC_NONE = "00"; // no SMSC Address
+
+const PDU_FIRST_OCTET = "00"; // RP:no, UDHI:no, SRI:no, MMS:no, MTI:SMS-DELIVER
+
+const PDU_SENDER_0 = "0A912143658709"; // +1234567890
+const PDU_SENDER_1 = "0A912143658719"; // +1234567891
+const SENDER_0 = "+1234567890";
+const SENDER_1 = "+1234567891";
+
+const PDU_PID_NORMAL = "00";
+const PDU_PIDS = ["00", "41", "42", "43", "44", "45", "46", "47"];
+
+const PDU_DCS_NORMAL = "00";
+
+const PDU_TIMESTAMP = "00101000000000"; // 2000/01/01
+
+const PDU_UDL = "01";
+const PDU_UD_A = "41"; // "A"
+const PDU_UD_B = "42"; // "B"
+const BODY_A = "A";
+const BODY_B = "B";
+
+function buildPdu(aSender, aPid, aBody) {
+  return PDU_SMSC_NONE + PDU_FIRST_OCTET + aSender + aPid + PDU_DCS_NORMAL +
+         PDU_TIMESTAMP + PDU_UDL + aBody;
+}
+
+let receivedMessage;
+function consumeReceivedMessage() {
+  let message = receivedMessage;
+  receivedMessage = null;
+  return message;
+}
+
+function waitForIncomingMessage() {
+  if (receivedMessage) {
+    return consumeReceivedMessage();
+  }
+
+  let deferred = Promise.defer();
+
+  waitFor(function() {
+    deferred.resolve(consumeReceivedMessage());
+  }, function() {
+    return receivedMessage != null;
+  });
+
+  return deferred.promise;
+}
+
+function sendRawSmsAndWait(aPdu) {
+  sendRawSmsToEmulator(aPdu);
+  return waitForIncomingMessage();
+}
+
+function verifyReplacing(aVictim, aSender, aPid, aCompare) {
+  let readableSender = aSender === PDU_SENDER_0 ? SENDER_0 : SENDER_1;
+  log("  Checking ('" + readableSender + "', '" + aPid + "', '" + BODY_B + "')");
+
+  let pdu = buildPdu(aSender, aPid, PDU_UD_B);
+  ok(true, "Sending " + pdu);
+
+  return sendRawSmsAndWait(pdu)
+    .then(function(aReceivedMessage) {
+      is(aReceivedMessage.sender, readableSender, "SmsMessage sender");
+      is(aReceivedMessage.body, BODY_B, "SmsMessage body");
+
+      aCompare(aReceivedMessage.id, aVictim.id, "SmsMessage id");
+    });
+}
+
+function verifyNotReplaced(aVictim, aSender, aPid) {
+  return verifyReplacing(aVictim, aSender, aPid, isnot);
+}
+
+function verifyReplaced(aVictim, aSender, aPid) {
+  return verifyReplacing(aVictim, aSender, aPid, is);
+}
+
+function testPid(aPid) {
+  log("Test message PID '" + aPid + "'");
+
+  return sendRawSmsAndWait(buildPdu(PDU_SENDER_0, aPid, PDU_UD_A))
+    .then(function(aReceivedMessage) {
+      let promise = Promise.resolve();
+
+      for (let pid of PDU_PIDS) {
+        let verify = (aPid !== PDU_PID_NORMAL && pid === aPid)
+                   ? verifyReplaced : verifyNotReplaced;
+        promise =
+          promise.then(verify.bind(null, aReceivedMessage, PDU_SENDER_0, pid))
+                 .then(verifyNotReplaced.bind(null, aReceivedMessage,
+                                              PDU_SENDER_1, pid));
+      }
+
+      return promise;
+    });
+}
+
+startTestCommon(function testCaseMain() {
+  manager.onreceived = function(event) {
+    receivedMessage = event.message;
+  };
+
+  let promise = Promise.resolve();
+  for (let pid of PDU_PIDS) {
+    promise = promise.then(testPid.bind(null, pid))
+                     .then(deleteAllMessages);
+  }
+
+  // Clear |manager.onreceived| handler.
+  return promise.then(function() {
+    manager.onreceived = null;
+  });
+});