Bug 1065591 Improve Loop xpcshell tests for MozLoopService to have a better chance of detecting coding errors. r=jaws
authorMark Banner <standard8@mozilla.com>
Thu, 11 Sep 2014 08:28:01 +0100
changeset 225341 8d53b9d6fc24043372253a86f9e9777720b68d61
parent 225340 aacb6173aedb15ae413c8154b1b7a16cabf2bd5c
child 225342 6858e2dbf7a5229d661a8d1565c022ca69444ff3
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws
bugs1065591
milestone34.0a2
Bug 1065591 Improve Loop xpcshell tests for MozLoopService to have a better chance of detecting coding errors. r=jaws
browser/components/loop/test/xpcshell/head.js
browser/components/loop/test/xpcshell/test_loopservice_dnd.js
browser/components/loop/test/xpcshell/test_loopservice_notification.js
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -22,38 +22,50 @@ const kEndPointUrl = "http://example.com
 const kUAID = "f47ac11b-58ca-4372-9567-0e02b2c3d479";
 
 // Fake loop server
 var loopServer;
 
 // Ensure loop is always enabled for tests
 Services.prefs.setBoolPref("loop.enabled", true);
 
-function hawkGetCallsRequest() {
-  let response = {body: JSON.stringify({calls: [{callId: 4444333221, websocketToken: "0deadbeef0"}]})},
-      // Call the first non-null then(resolve) function attached to the fakePromise.
-      fakePromise = {then: (resolve) => {return resolve ? resolve(response) : fakePromise;},
-                     catch: () => {return fakePromise;}};
-  return fakePromise;
-}
-
 function setupFakeLoopServer() {
   loopServer = new HttpServer();
   loopServer.start(-1);
 
   Services.prefs.setCharPref("services.push.serverURL", kServerPushUrl);
 
   Services.prefs.setCharPref("loop.server",
     "http://localhost:" + loopServer.identity.primaryPort);
 
   do_register_cleanup(function() {
     loopServer.stop(function() {});
   });
 }
 
+function waitForCondition(aConditionFn, aMaxTries=50, aCheckInterval=100) {
+  function tryAgain() {
+    function tryNow() {
+      tries++;
+      if (aConditionFn()) {
+        deferred.resolve();
+      } else if (tries < aMaxTries) {
+        tryAgain();
+      } else {
+        deferred.reject("Condition timed out: " + aConditionFn.toSource());
+      }
+    }
+    do_timeout(aCheckInterval, tryNow);
+  }
+  let deferred = Promise.defer();
+  let tries = 0;
+  tryAgain();
+  return deferred.promise;
+}
+
 /**
  * This is used to fake push registration and notifications for
  * MozLoopService tests. There is only one object created per test instance, as
  * once registration has taken place, the object cannot currently be changed.
  */
 let mockPushHandler = {
   // This sets the registration result to be returned when initialize
   // is called. By default, it is equivalent to success.
--- a/browser/components/loop/test/xpcshell/test_loopservice_dnd.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_dnd.js
@@ -1,18 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 XPCOMUtils.defineLazyModuleGetter(this, "Chat",
                                   "resource:///modules/Chat.jsm");
 let openChatOrig = Chat.open;
 
-const loopServiceModule = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
-
 add_test(function test_get_do_not_disturb() {
   Services.prefs.setBoolPref("loop.do_not_disturb", false);
 
   do_check_false(MozLoopService.doNotDisturb);
 
   Services.prefs.setBoolPref("loop.do_not_disturb", true);
 
   do_check_true(MozLoopService.doNotDisturb);
@@ -34,52 +32,58 @@ add_test(function test_do_not_disturb_di
   MozLoopService.doNotDisturb = false;
 
   MozLoopService.register(mockPushHandler).then(() => {
     let opened = false;
     Chat.open = function() {
       opened = true;
     };
 
-    let savedHawkClient = loopServiceModule.gHawkClient;
-    loopServiceModule.gHawkClient = {request: hawkGetCallsRequest};
-
     mockPushHandler.notify(1);
 
-    do_check_true(opened, "should open a chat window");
-
-    loopServiceModule.gHawkClient = savedHawkClient;
-
-    run_next_test();
+    waitForCondition(function() opened).then(() => {
+      run_next_test();
+    }, () => {
+      do_throw("should have opened a chat window");
+    });
   });
 });
 
-add_task(function test_do_not_disturb_enabled_shouldnt_open_chat_window() {
+add_test(function test_do_not_disturb_enabled_shouldnt_open_chat_window() {
   MozLoopService.doNotDisturb = true;
 
   // We registered in the previous test, so no need to do that on this one.
   let opened = false;
   Chat.open = function() {
     opened = true;
   };
 
   mockPushHandler.notify(1);
 
-  do_check_false(opened, "should not open a chat window");
+  do_timeout(500, function() {
+    do_check_false(opened, "should not open a chat window");
+    run_next_test();
+  });
 });
 
 function run_test()
 {
   setupFakeLoopServer();
 
   loopServer.registerPathHandler("/registration", (request, response) => {
     response.setStatusLine(null, 200, "OK");
     response.processAsync();
     response.finish();
   });
+  loopServer.registerPathHandler("/calls", (request, response) => {
+    response.setStatusLine(null, 200, "OK");
+    response.write(JSON.stringify({calls: [{callId: 4444333221, websocketToken: "0deadbeef0"}]}));
+    response.processAsync();
+    response.finish();
+  });
 
   do_register_cleanup(function() {
     // Revert original Chat.open implementation
     Chat.open = openChatOrig;
 
     // clear test pref
     Services.prefs.clearUserPref("loop.do_not_disturb");
   });
--- a/browser/components/loop/test/xpcshell/test_loopservice_notification.js
+++ b/browser/components/loop/test/xpcshell/test_loopservice_notification.js
@@ -13,41 +13,47 @@ add_test(function test_openChatWindow_on
   Services.prefs.setCharPref("loop.seenToS", "unseen");
 
   MozLoopService.register(mockPushHandler).then(() => {
     let opened = false;
     Chat.open = function() {
       opened = true;
     };
 
-    let savedHawkClient = loopServiceModule.gHawkClient;
-    loopServiceModule.gHawkClient = {request: hawkGetCallsRequest};
-
     mockPushHandler.notify(1);
 
-    do_check_true(opened, "should open a chat window");
+    waitForCondition(function() opened).then(() => {
+      do_check_true(opened, "should open a chat window");
+
+      do_check_eq(Services.prefs.getCharPref("loop.seenToS"), "seen",
+                  "should set the pref to 'seen'");
 
-    do_check_eq(Services.prefs.getCharPref("loop.seenToS"), "seen",
-                "should set the pref to 'seen'");
+      run_next_test();
+    }, () => {
+      do_throw("should have opened a chat window");
+    });
 
-    loopServiceModule.gHawkClient = savedHawkClient;
-
-    run_next_test();
   });
 });
 
 function run_test()
 {
   setupFakeLoopServer();
 
   loopServer.registerPathHandler("/registration", (request, response) => {
     response.setStatusLine(null, 200, "OK");
     response.processAsync();
     response.finish();
   });
+  loopServer.registerPathHandler("/calls", (request, response) => {
+    response.setStatusLine(null, 200, "OK");
+    response.write(JSON.stringify({calls: [{callId: 4444333221, websocketToken: "0deadbeef0"}]}));
+    response.processAsync();
+    response.finish();
+  });
 
   do_register_cleanup(function() {
     // Revert original Chat.open implementation
     Chat.open = openChatOrig;
 
     // clear test pref
     Services.prefs.clearUserPref("loop.seenToS");
   });