Bug 882496 - Fail gracefully if Persona observer methods called before watch(). r=benadida
authorJed Parsons <jparsons@mozilla.com>
Thu, 13 Jun 2013 17:44:44 -0700
changeset 135838 e09d80620b6994cd1b0f75d093ef45fbfc4f037e
parent 135837 b1252db21280e9bfb5f42043b3b03d22cd96d13e
child 135839 14967188583ef1f76b31ecae435acda5bcd56462
push id24852
push userryanvm@gmail.com
push dateThu, 20 Jun 2013 23:22:28 +0000
treeherdermozilla-central@b3cbafd5eb99 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbenadida
bugs882496
milestone24.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 882496 - Fail gracefully if Persona observer methods called before watch(). r=benadida
toolkit/identity/MinimalIdentity.jsm
toolkit/identity/tests/unit/test_minimalidentity.js
--- a/toolkit/identity/MinimalIdentity.jsm
+++ b/toolkit/identity/MinimalIdentity.jsm
@@ -142,16 +142,20 @@ IDService.prototype = {
   },
 
   /*
    * The RP has gone away; remove handles to the hidden iframe.
    * It's probable that the frame will already have been cleaned up.
    */
   unwatch: function unwatch(aRpId, aTargetMM) {
     let rp = this._rpFlows[aRpId];
+    if (!rp) {
+      return;
+    }
+
     let options = makeMessageObject({
       id: aRpId,
       origin: rp.origin,
       messageManager: aTargetMM
     });
     log("sending identity-controller-unwatch for id", options.id, options.origin);
     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-unwatch", null);
 
@@ -166,16 +170,20 @@ IDService.prototype = {
    * @param aRPId
    *        (integer)  the id of the doc object obtained in .watch()
    *
    * @param aOptions
    *        (Object)  options including privacyPolicy, termsOfService
    */
   request: function request(aRPId, aOptions) {
     let rp = this._rpFlows[aRPId];
+    if (!rp) {
+      reportError("request() called before watch()");
+      return;
+    }
 
     // Notify UX to display identity picker.
     // Pass the doc id to UX so it can pass it back to us later.
     let options = makeMessageObject(rp);
     objectCopy(aOptions, options);
     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-request", null);
   },
 
@@ -184,16 +192,20 @@ IDService.prototype = {
    * on an in-content logout button).
    *
    * @param aRpCallerId
    *        (integer)  the id of the doc object obtained in .watch()
    *
    */
   logout: function logout(aRpCallerId) {
     let rp = this._rpFlows[aRpCallerId];
+    if (!rp) {
+      reportError("logout() called before watch()");
+      return;
+    }
 
     let options = makeMessageObject(rp);
     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-controller-logout", null);
   },
 
   childProcessShutdown: function childProcessShutdown(messageManager) {
     let options = makeMessageObject({messageManager: messageManager, id: null, origin: null});
     Services.obs.notifyObservers({wrappedJSObject: options}, "identity-child-process-shutdown", null);
--- a/toolkit/identity/tests/unit/test_minimalidentity.js
+++ b/toolkit/identity/tests/unit/test_minimalidentity.js
@@ -111,23 +111,74 @@ function test_logout() {
     do_test_finished();
     run_next_test();
   });
 
   MinimalIDService.RP.watch(mockedDoc);
   MinimalIDService.RP.logout(mockedDoc.id, {});
 }
 
+/*
+ * Test that logout() before watch() fails gently
+ */
+
+function test_logoutBeforeWatch() {
+  do_test_pending();
+
+  let mockedDoc = mock_doc(null, TEST_URL);
+  makeObserver("identity-controller-logout", function() {
+    do_throw("How can we logout when watch was not called?");
+  });
+
+  MinimalIDService.RP.logout(mockedDoc.id, {});
+  do_test_finished();
+  run_next_test();
+}
+
+/*
+ * Test that request() before watch() fails gently
+ */
+
+function test_requestBeforeWatch() {
+  do_test_pending();
+
+  let mockedDoc = mock_doc(null, TEST_URL);
+  makeObserver("identity-controller-request", function() {
+    do_throw("How can we request when watch was not called?");
+  });
+
+  MinimalIDService.RP.request(mockedDoc.id, {});
+  do_test_finished();
+  run_next_test();
+}
+
+/*
+ * Test that internal unwatch() before watch() fails gently
+ */
+
+function test_unwatchBeforeWatch() {
+  do_test_pending();
+
+  let mockedDoc = mock_doc(null, TEST_URL);
+
+  MinimalIDService.RP.unwatch(mockedDoc.id, {});
+  do_test_finished();
+  run_next_test();
+}
+
 let TESTS = [
   test_overall,
   test_mock_doc,
   test_watch,
   test_request,
   test_request_forceAuthentication,
   test_request_forceIssuer,
-  test_logout
+  test_logout,
+  test_logoutBeforeWatch,
+  test_requestBeforeWatch,
+  test_unwatchBeforeWatch
 ];
 
 TESTS.forEach(add_test);
 
 function run_test() {
   run_next_test();
 }