Bug 824717 - Part 7: Modify and Add test cases to check the message id and message content when failed to send SMS/MMS message. r=vyang
authorBevis Tseng <btseng@mozilla.com>
Tue, 29 Apr 2014 17:04:42 +0800
changeset 185278 22b5eefc275433bff9f2030504a6c95e4df0a2cf
parent 185277 b46bd7827ccf9511b46874305e40b5922da3af2e
child 185279 8331da4219d87d9eb90cb54a7fad608c0e47562b
push id26847
push usercbook@mozilla.com
push dateWed, 28 May 2014 12:34:11 +0000
treeherdermozilla-central@5add3261493b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvyang
bugs824717
milestone32.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 824717 - Part 7: Modify and Add test cases to check the message id and message content when failed to send SMS/MMS message. r=vyang
dom/mobilemessage/tests/marionette/head.js
dom/mobilemessage/tests/marionette/manifest.ini
dom/mobilemessage/tests/marionette/test_error_of_mms_send.js
dom/mobilemessage/tests/marionette/test_error_of_sms_send.js
--- a/dom/mobilemessage/tests/marionette/head.js
+++ b/dom/mobilemessage/tests/marionette/head.js
@@ -66,42 +66,94 @@ function waitForManagerEvent(aEventName)
     ok(true, "MobileMessageManager event '" + aEventName + "' got.");
     deferred.resolve(aEvent);
   });
 
   return deferred.promise;
 }
 
 /**
+ * Wrap DOMRequest onsuccess/onerror events to Promise resolve/reject.
+ *
+ * Fulfill params: A DOMEvent.
+ * Reject params: A DOMEvent.
+ *
+ * @param aRequest
+ *        A DOMRequest instance.
+ *
+ * @return A deferred promise.
+ */
+function wrapDomRequestAsPromise(aRequest) {
+  let deferred = Promise.defer();
+
+  ok(aRequest instanceof DOMRequest,
+     "aRequest is instanceof " + aRequest.constructor);
+
+  aRequest.addEventListener("success", function(aEvent) {
+    deferred.resolve(aEvent);
+  });
+  aRequest.addEventListener("error", function(aEvent) {
+    deferred.reject(aEvent);
+  });
+
+  return deferred.promise;
+}
+
+/**
  * Send a SMS message to a single receiver.  Resolve if it succeeds, reject
  * otherwise.
  *
  * Fulfill params:
  *   message -- the sent SmsMessage.
  *
  * Reject params:
  *   error -- a DOMError.
  *
  * @param aReceiver the address of the receiver.
  * @param aText the text body of the message.
  *
  * @return A deferred promise.
  */
 function sendSmsWithSuccess(aReceiver, aText) {
-  let deferred = Promise.defer();
+  let request = manager.send(aReceiver, aText);
+  return wrapDomRequestAsPromise(request)
+    .then((aEvent) => { return aEvent.target.result; },
+          (aEvent) => { throw aEvent.target.error; });
+}
+
+/**
+ * Send a SMS message to a single receiver.
+ * Resolve if it fails, reject otherwise.
+ *
+ * Fulfill params:
+ *   {
+ *     message,  -- the failed MmsMessage
+ *     error,    -- error of the send request
+ *   }
+ *
+ * Reject params: (none)
+ *
+ * @param aReceiver the address of the receiver.
+ * @param aText the text body of the message.
+ *
+ * @return A deferred promise.
+ */
+function sendSmsWithFailure(aReceiver, aText) {
+  let promises = [];
+  promises.push(waitForManagerEvent("failed")
+    .then((aEvent) => { return aEvent.message; }));
 
   let request = manager.send(aReceiver, aText);
-  request.onsuccess = function(event) {
-    deferred.resolve(event.target.result);
-  };
-  request.onerror = function(event) {
-    deferred.reject(event.target.error);
-  };
+  promises.push(wrapDomRequestAsPromise(request)
+    .then((aEvent) => { throw aEvent; },
+          (aEvent) => { return aEvent.target.error; }));
 
-  return deferred.promise;
+  return Promise.all(promises)
+    .then((aResults) => { return { message: aResults[0],
+                                   error: aResults[1] }; });
 }
 
 /**
  * Send a MMS message with specified parameters.  Resolve if it fails, reject
  * otherwise.
  *
  * Fulfill params:
  *   {
@@ -113,40 +165,28 @@ function sendSmsWithSuccess(aReceiver, a
  *
  * @param aMmsParameters a MmsParameters instance.
  *
  * @param aSendParameters a MmsSendParameters instance.
  *
  * @return A deferred promise.
  */
 function sendMmsWithFailure(aMmsParameters, aSendParameters) {
-  let deferred = Promise.defer();
-
-  let result = { message: null, error: null };
-  function got(which, value) {
-    result[which] = value;
-    if (result.message != null && result.error != null) {
-      deferred.resolve(result);
-    }
-  }
-
-  manager.addEventListener("failed", function onfailed(event) {
-    manager.removeEventListener("failed", onfailed);
-    got("message", event.message);
-  });
+  let promises = [];
+  promises.push(waitForManagerEvent("failed")
+    .then((aEvent) => { return aEvent.message; }));
 
   let request = manager.sendMMS(aMmsParameters, aSendParameters);
-  request.onsuccess = function(event) {
-    deferred.reject();
-  };
-  request.onerror = function(event) {
-    got("error", event.target.error);
-  }
+  promises.push(wrapDomRequestAsPromise(request)
+    .then((aEvent) => { throw aEvent; },
+          (aEvent) => { return aEvent.target.error; }));
 
-  return deferred.promise;
+  return Promise.all(promises)
+    .then((aResults) => { return { message: aResults[0],
+                                   error: aResults[1] }; });
 }
 
 /**
  * Retrieve messages from database.
  *
  * Fulfill params:
  *   messages -- an array of {Sms,Mms}Message instances.
  *
@@ -267,25 +307,19 @@ function getThreadById(aThreadId) {
  * @return An empty array if nothing to be deleted; otherwise, a deferred promise.
  */
 function deleteMessagesById(aMessageIds) {
   if (!aMessageIds.length) {
     ok(true, "no message to be deleted");
     return [];
   }
 
-  let deferred = Promise.defer();
-
   let request = manager.delete(aMessageIds);
-  request.onsuccess = function(event) {
-    deferred.resolve(event.target.result);
-  };
-  request.onerror = deferred.reject.bind(deferred);
-
-  return deferred.promise;
+  return wrapDomRequestAsPromise(request)
+      .then((aEvent) => { return aEvent.target.result; });
 }
 
 /**
  * Delete messages specified from database.
  *
  * Fulfill params:
  *   result -- an array of boolean values indicating whether delesion was
  *             actually performed on the message record with corresponding id.
--- a/dom/mobilemessage/tests/marionette/manifest.ini
+++ b/dom/mobilemessage/tests/marionette/manifest.ini
@@ -44,8 +44,9 @@ qemu = true
 [test_mmdb_foreachmatchedmmsdeliveryinfo.js]
 [test_mmdb_full_storage.js]
 [test_mmdb_upgradeSchema_current_structure.js]
 [test_mmdb_upgradeSchema_22.js]
 [test_replace_short_message_type.js]
 [test_mt_sms_concatenation.js]
 [test_error_of_mms_manual_retrieval.js]
 [test_error_of_mms_send.js]
+[test_error_of_sms_send.js]
--- a/dom/mobilemessage/tests/marionette/test_error_of_mms_send.js
+++ b/dom/mobilemessage/tests/marionette/test_error_of_mms_send.js
@@ -9,23 +9,41 @@ const kPrefRilRadioDisabled  = "ril.radi
 function testSendFailed(aCause, aServiceId) {
   log("testSendFailed, aCause: " + aCause + ", aServiceId: " + aServiceId);
   let sendParameters;
 
   if (aServiceId) {
     sendParameters = { serviceId: aServiceId };
   }
 
-  let mmsParameters = { subject: "Test",
-                        receivers: ["+0987654321"],
+  let testSubject = "Test";
+  let testReceivers = ["+0987654321"];
+
+  let mmsParameters = { subject: testSubject,
+                        receivers: testReceivers,
                         attachments: [] };
 
   return sendMmsWithFailure(mmsParameters, sendParameters)
     .then((result) => {
       is(result.error.name, aCause, "Checking failure cause.");
+
+      let domMessage = result.error.data;
+      is(domMessage.id, result.message.id, "Checking message id.");
+      is(domMessage.subject, testSubject, "Checking subject.");
+      is(domMessage.receivers.length, testReceivers.length, "Checking no. of receivers.");
+      for (let i = 0; i < testReceivers.length; i++) {
+        is(domMessage.receivers[i], testReceivers[i], "Checking receiver address.");
+      }
+
+      let deliveryInfo = domMessage.deliveryInfo;
+      is(deliveryInfo.length, testReceivers.length, "Checking no. of deliveryInfo.");
+      for (let i = 0; i < deliveryInfo.length; i++) {
+        is(deliveryInfo[i].receiver, testReceivers[i], "Checking receiver address.");
+        is(deliveryInfo[i].deliveryStatus, "error", "Checking deliveryStatus.");
+      }
     });
 }
 
 startTestCommon(function testCaseMain() {
   return Promise.resolve()
     .then(() => {
       SpecialPowers.setBoolPref(kPrefRilRadioDisabled, true);
     })
new file mode 100644
--- /dev/null
+++ b/dom/mobilemessage/tests/marionette/test_error_of_sms_send.js
@@ -0,0 +1,105 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 60000;
+MARIONETTE_HEAD_JS = 'head.js';
+
+const kPrefRilRadioDisabled  = "ril.radio.disabled";
+
+let connection;
+function ensureMobileConnection() {
+  let deferred = Promise.defer();
+
+  let permissions = [{
+    "type": "mobileconnection",
+    "allow": true,
+    "context": document,
+  }];
+  SpecialPowers.pushPermissions(permissions, function() {
+    ok(true, "permissions pushed: " + JSON.stringify(permissions));
+
+    connection = window.navigator.mozMobileConnections[0];
+    if (connection) {
+      log("navigator.mozMobileConnections[0] is instance of " + connection.constructor);
+    } else {
+      log("navigator.mozMobileConnections[0] is undefined.");
+    }
+
+    if (connection instanceof MozMobileConnection) {
+      deferred.resolve(connection);
+    } else {
+      deferred.reject();
+    }
+  });
+
+  return deferred.promise;
+}
+
+function waitRadioState(state) {
+  let deferred = Promise.defer();
+
+  waitFor(function() {
+    deferred.resolve();
+  }, function() {
+    return connection.radioState == state;
+  });
+
+  return deferred.promise;
+}
+
+function setRadioEnabled(enabled) {
+  log("setRadioEnabled to " + enabled);
+
+  let deferred = Promise.defer();
+
+  let finalState = (enabled) ? "enabled" : "disabled";
+  connection.onradiostatechange = function() {
+    let state = connection.radioState;
+    log("Received 'radiostatechange' event, radioState: " + state);
+
+    if (state == finalState) {
+      deferred.resolve();
+      connection.onradiostatechange = null;
+    }
+  };
+
+  let req = connection.setRadioEnabled(enabled);
+
+  req.onsuccess = function() {
+    log("setRadioEnabled success");
+  };
+
+  req.onerror = function() {
+    ok(false, "setRadioEnabled should not fail");
+    deferred.reject();
+  };
+
+  return deferred.promise;
+}
+
+function testSendFailed(aCause) {
+  log("testSendFailed, aCause: " + aCause);
+
+  let testReceiver = "+0987654321";
+  let testMessage = "quick fox jump over the lazy dog";
+
+  return sendSmsWithFailure(testReceiver, testMessage)
+    .then((result) => {
+      is(result.error.name, aCause, "Checking failure cause.");
+
+      let domMessage = result.error.data;
+      is(domMessage.id, result.message.id, "Checking message id.");
+      is(domMessage.receiver, testReceiver, "Checking receiver address.");
+      is(domMessage.body, testMessage, "Checking message body.");
+      is(domMessage.delivery, "error", "Checking delivery.");
+      is(domMessage.deliveryStatus, "error", "Checking deliveryStatus.");
+    });
+}
+
+startTestCommon(function testCaseMain() {
+  return ensureMobileConnection()
+    .then(() => waitRadioState("enabled"))
+    .then(() => setRadioEnabled(false))
+    .then(() => testSendFailed("RadioDisabledError"))
+    .then(() => setRadioEnabled(true));
+});