Bug 1088465 - MozLoopService: Use a |mocks| property instead of passing arguments through registration. r=mikedeboer

This commit is contained in:
Mike de Boer
2014-10-27 11:11:36 +01:00
parent 485dda2df4
commit 7eeab2f806
14 changed files with 89 additions and 94 deletions

View File

@@ -179,8 +179,13 @@ CallProgressSocket.prototype = {
* and register with the Loop server.
*/
let LoopCallsInternal = {
callsData: {inUse: false},
_mocks: {webSocket: undefined},
callsData: {
inUse: false,
},
mocks: {
webSocket: undefined,
},
/**
* Callback from MozLoopPushHandler - A push notification has been received from
@@ -308,7 +313,9 @@ let LoopCallsInternal = {
callData.progressURL,
callData.callId,
callData.websocketToken);
callProgress._websocket = this._mocks.webSocket;
if (this.mocks.webSocket) {
callProgress._websocket = this.mocks.webSocket;
}
// This instance of CallProgressSocket should stay alive until the underlying
// websocket is closed since it is passed to the websocket as the nsIWebSocketListener.
callProgress.connect(() => {callProgress.sendBusy();});

View File

@@ -109,7 +109,6 @@ function getJSONPref(aName) {
// or the registration was successful. This is null if a registration attempt was
// unsuccessful.
let gRegisteredDeferred = null;
let gPushHandler = null;
let gHawkClient = null;
let gLocalizedStrings = null;
let gInitializeTimer = null;
@@ -126,7 +125,12 @@ let gErrors = new Map();
* and register with the Loop server.
*/
let MozLoopServiceInternal = {
_mocks: {webSocket: undefined},
mocks: {
pushHandler: undefined,
webSocket: undefined,
},
get pushHandler() this.mocks.pushHandler || MozLoopPushHandler,
// The uri of the Loop server.
get loopServerUri() Services.prefs.getCharPref("loop.server"),
@@ -307,21 +311,14 @@ let MozLoopServiceInternal = {
* Starts registration of Loop with the push server, and then will register
* with the Loop server. It will return early if already registered.
*
* @param {Object} mockPushHandler Optional, test-only mock push handler. Used
* to allow mocking of the MozLoopPushHandler.
* @param {Object} mockWebSocket Optional, test-only mock webSocket. To be passed
* through to MozLoopPushHandler.
* @returns {Promise} a promise that is resolved with no params on completion, or
* rejected with an error code or string.
*/
promiseRegisteredWithServers: function(mockPushHandler, mockWebSocket) {
promiseRegisteredWithServers: function() {
if (gRegisteredDeferred) {
return gRegisteredDeferred.promise;
}
this._mocks.webSocket = mockWebSocket;
this._mocks.pushHandler = mockPushHandler;
// Wrap push notification registration call-back in a Promise.
let registerForNotification = function(channelID, onNotification) {
return new Promise((resolve, reject) => {
@@ -332,7 +329,7 @@ let MozLoopServiceInternal = {
resolve(pushUrl);
}
};
gPushHandler.register(channelID, onRegistered, onNotification);
MozLoopServiceInternal.pushHandler.register(channelID, onRegistered, onNotification);
});
};
@@ -341,27 +338,28 @@ let MozLoopServiceInternal = {
// it back to null on error.
let result = gRegisteredDeferred.promise;
gPushHandler = mockPushHandler || MozLoopPushHandler;
let options = mockWebSocket ? {mockWebSocket: mockWebSocket} : {};
gPushHandler.initialize(options);
let options = this.mocks.webSocket ? { mockWebSocket: this.mocks.webSocket } : {};
this.pushHandler.initialize(options);
let callsRegGuest = registerForNotification(MozLoopService.channelIDs.callsGuest,
LoopCalls.onNotification);
let roomsRegGuest = registerForNotification(MozLoopService.channelIDs.roomsGuest,
roomsPushNotification);
let callsRegFxA = registerForNotification(MozLoopService.channelIDs.callsFxA,
LoopCalls.onNotification);
let roomsRegFxA = registerForNotification(MozLoopService.channelIDs.roomsFxA,
roomsPushNotification);
Promise.all([callsRegGuest, roomsRegGuest, callsRegFxA, roomsRegFxA])
.then((pushUrls) => {
return this.registerWithLoopServer(LOOP_SESSION_TYPE.GUEST,
{calls: pushUrls[0], rooms: pushUrls[1]}) })
.then(() => {
return this.registerWithLoopServer(LOOP_SESSION_TYPE.GUEST,{
calls: pushUrls[0],
rooms: pushUrls[1],
});
}).then(() => {
// storeSessionToken could have rejected and nulled the promise if the token was malformed.
if (!gRegisteredDeferred) {
return;
@@ -873,13 +871,13 @@ let MozLoopServiceInternal = {
};
Object.freeze(MozLoopServiceInternal);
let gInitializeTimerFunc = (deferredInitialization, mockPushHandler, mockWebSocket) => {
let gInitializeTimerFunc = (deferredInitialization) => {
// Kick off the push notification service into registering after a timeout.
// This ensures we're not doing too much straight after the browser's finished
// starting up.
gInitializeTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
gInitializeTimer.initWithCallback(Task.async(function* initializationCallback() {
yield MozLoopService.register(mockPushHandler, mockWebSocket).then(Task.async(function*() {
yield MozLoopService.register().then(Task.async(function*() {
if (!MozLoopServiceInternal.fxAOAuthTokenData) {
log.debug("MozLoopService: Initialized without an already logged-in account");
deferredInitialization.resolve("initialized to guest status");
@@ -890,8 +888,8 @@ let gInitializeTimerFunc = (deferredInitialization, mockPushHandler, mockWebSock
let registeredPromise =
MozLoopServiceInternal.registerWithLoopServer(
LOOP_SESSION_TYPE.FXA, {
calls: gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
rooms: gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA]
calls: MozLoopServiceInternal.pushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
rooms: MozLoopServiceInternal.pushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA]
});
registeredPromise.then(() => {
deferredInitialization.resolve("initialized to logged-in status");
@@ -936,7 +934,7 @@ this.MozLoopService = {
*
* @return {Promise}
*/
initialize: Task.async(function*(mockPushHandler, mockWebSocket) {
initialize: Task.async(function*() {
// Do this here, rather than immediately after definition, so that we can
// stub out API functions for unit testing
Object.freeze(this);
@@ -962,7 +960,7 @@ this.MozLoopService = {
}
let deferredInitialization = Promise.defer();
gInitializeTimerFunc(deferredInitialization, mockPushHandler, mockWebSocket);
gInitializeTimerFunc(deferredInitialization);
return deferredInitialization.promise.catch(error => {
if (typeof(error) == "object") {
@@ -1088,12 +1086,10 @@ this.MozLoopService = {
* Starts registration of Loop with the push server, and then will register
* with the Loop server. It will return early if already registered.
*
* @param {Object} mockPushHandler Optional, test-only mock push handler. Used
* to allow mocking of the MozLoopPushHandler.
* @returns {Promise} a promise that is resolved with no params on completion, or
* rejected with an error code or string.
*/
register: function(mockPushHandler, mockWebSocket) {
register: function() {
log.debug("registering");
// Don't do anything if loop is not enabled.
if (!Services.prefs.getBoolPref("loop.enabled")) {
@@ -1104,7 +1100,7 @@ this.MozLoopService = {
throw new Error("Loop is disabled by the soft-start mechanism");
}
return MozLoopServiceInternal.promiseRegisteredWithServers(mockPushHandler, mockWebSocket);
return MozLoopServiceInternal.promiseRegisteredWithServers();
},
/**
@@ -1301,8 +1297,8 @@ this.MozLoopService = {
return tokenData;
}).then(tokenData => {
return gRegisteredDeferred.promise.then(Task.async(function*() {
let callsUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
roomsUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
let callsUrl = MozLoopServiceInternal.pushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA],
roomsUrl = MozLoopServiceInternal.pushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
if (callsUrl && roomsUrl) {
yield MozLoopServiceInternal.registerWithLoopServer(
LOOP_SESSION_TYPE.FXA, {calls: callsUrl, rooms: roomsUrl});
@@ -1348,23 +1344,19 @@ this.MozLoopService = {
*/
logOutFromFxA: Task.async(function*() {
log.debug("logOutFromFxA");
let callsPushUrl, roomsPushUrl;
if (gPushHandler) {
callsPushUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA];
roomsPushUrl = gPushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
}
let pushHandler = MozLoopServiceInternal.pushHandler;
let callsPushUrl = pushHandler.registeredChannels[MozLoopService.channelIDs.callsFxA];
let roomsPushUrl = pushHandler.registeredChannels[MozLoopService.channelIDs.roomsFxA];
try {
if (callsPushUrl) {
yield MozLoopServiceInternal.unregisterFromLoopServer(
LOOP_SESSION_TYPE.FXA, callsPushUrl);
yield MozLoopServiceInternal.unregisterFromLoopServer(LOOP_SESSION_TYPE.FXA, callsPushUrl);
}
if (roomsPushUrl) {
yield MozLoopServiceInternal.unregisterFromLoopServer(
LOOP_SESSION_TYPE.FXA, roomsPushUrl);
yield MozLoopServiceInternal.unregisterFromLoopServer(LOOP_SESSION_TYPE.FXA, roomsPushUrl);
}
}
catch (error) {throw error}
finally {
} catch (error) {
throw error;
} finally {
MozLoopServiceInternal.clearSessionToken(LOOP_SESSION_TYPE.FXA);
}

View File

@@ -40,11 +40,13 @@ function* checkFxA401() {
add_task(function* setup() {
Services.prefs.setCharPref("loop.server", BASE_URL);
Services.prefs.setCharPref("services.push.serverURL", "ws://localhost/");
MozLoopServiceInternal.mocks.pushHandler = mockPushHandler;
registerCleanupFunction(function* () {
info("cleanup time");
yield promiseDeletedOAuthParams(BASE_URL);
Services.prefs.clearUserPref("loop.server");
Services.prefs.clearUserPref("services.push.serverURL");
MozLoopServiceInternal.mocks.pushHandler = undefined;
yield resetFxA();
Services.prefs.clearUserPref(MozLoopServiceInternal.getSessionTokenPrefName(LOOP_SESSION_TYPE.GUEST));
});
@@ -251,7 +253,7 @@ add_task(function* basicAuthorizationAndRegistration() {
mockPushHandler.registrationPushURL = "https://localhost/pushUrl/guest";
// Notification observed due to the error being cleared upon successful registration.
let statusChangedPromise = promiseObserverNotified("loop-status-changed");
yield MozLoopService.register(mockPushHandler);
yield MozLoopService.register();
yield statusChangedPromise;
// Normally the same pushUrl would be registered but we change it in the test
@@ -316,7 +318,7 @@ add_task(function* loginWithParams401() {
test_error: "params_401",
};
yield promiseOAuthParamsSetup(BASE_URL, params);
yield MozLoopService.register(mockPushHandler);
yield MozLoopService.register();
let loginPromise = MozLoopService.logInToFxA();
yield loginPromise.then(tokenData => {

View File

@@ -40,8 +40,11 @@ function setupFakeLoopServer() {
Services.prefs.setCharPref("loop.server",
"http://localhost:" + loopServer.identity.primaryPort);
MozLoopServiceInternal.mocks.pushHandler = mockPushHandler;
do_register_cleanup(function() {
loopServer.stop(function() {});
MozLoopServiceInternal.mocks.pushHandler = undefined;
});
}

View File

@@ -19,17 +19,12 @@ let msgHandler = function(msg) {
msg.reason === "busy") {
actionReceived = true;
}
}
let mockWebSocket = new MockWebSocketChannel({defaultMsgHandler: msgHandler});
LoopCallsInternal._mocks.webSocket = mockWebSocket;
Services.io.offline = false;
};
add_test(function test_busy_2guest_calls() {
actionReceived = false;
MozLoopService.register(mockPushHandler, mockWebSocket).then(() => {
MozLoopService.register().then(() => {
let opened = 0;
Chat.open = function() {
opened++;
@@ -52,7 +47,7 @@ add_test(function test_busy_2guest_calls() {
add_test(function test_busy_1fxa_1guest_calls() {
actionReceived = false;
MozLoopService.register(mockPushHandler, mockWebSocket).then(() => {
MozLoopService.register().then(() => {
let opened = 0;
Chat.open = function() {
opened++;
@@ -76,7 +71,7 @@ add_test(function test_busy_1fxa_1guest_calls() {
add_test(function test_busy_2fxa_calls() {
actionReceived = false;
MozLoopService.register(mockPushHandler, mockWebSocket).then(() => {
MozLoopService.register().then(() => {
let opened = 0;
Chat.open = function() {
opened++;
@@ -99,7 +94,7 @@ add_test(function test_busy_2fxa_calls() {
add_test(function test_busy_1guest_1fxa_calls() {
actionReceived = false;
MozLoopService.register(mockPushHandler, mockWebSocket).then(() => {
MozLoopService.register().then(() => {
let opened = 0;
Chat.open = function() {
opened++;
@@ -120,8 +115,7 @@ add_test(function test_busy_1guest_1fxa_calls() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
// Setup fake login state so we get FxA requests.
@@ -129,6 +123,11 @@ function run_test()
MozLoopServiceInternal.fxAOAuthTokenData = {token_type:"bearer",access_token:"1bad3e44b12f77a88fe09f016f6a37c42e40f974bc7a8b432bb0d2f0e37e1752",scope:"profile"};
MozLoopServiceInternal.fxAOAuthProfile = {email: "test@example.com", uid: "abcd1234"};
let mockWebSocket = new MockWebSocketChannel({defaultMsgHandler: msgHandler});
LoopCallsInternal.mocks.webSocket = mockWebSocket;
Services.io.offline = false;
// For each notification received from the PushServer, MozLoopService will first query
// for any pending calls on the FxA hawk session and then again using the guest session.
// A pair of response objects in the callsResponses array will be consumed for each
@@ -178,7 +177,7 @@ function run_test()
// clear test pref
Services.prefs.clearUserPref("loop.seenToS");
LoopCallsInternal._mocks.webSocket = undefined;
LoopCallsInternal.mocks.webSocket = undefined;
});
run_next_test();

View File

@@ -31,7 +31,7 @@ add_test(function test_set_do_not_disturb() {
add_test(function test_do_not_disturb_disabled_should_open_chat_window() {
MozLoopService.doNotDisturb = false;
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
let opened = false;
Chat.open = function() {
opened = true;
@@ -64,8 +64,7 @@ add_test(function test_do_not_disturb_enabled_shouldnt_open_chat_window() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
loopServer.registerPathHandler("/registration", (request, response) => {

View File

@@ -10,7 +10,7 @@ let openChatOrig = Chat.open;
add_test(function test_openChatWindow_on_notification() {
Services.prefs.setCharPref("loop.seenToS", "unseen");
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
let opened = false;
Chat.open = function() {
opened = true;
@@ -32,8 +32,7 @@ add_test(function test_openChatWindow_on_notification() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
loopServer.registerPathHandler("/registration", (request, response) => {

View File

@@ -17,7 +17,7 @@ Cu.import("resource://services-common/utils.js");
add_test(function test_register_websocket_success_loop_server_fail() {
mockPushHandler.registrationResult = "404";
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
do_throw("should not succeed when loop server registration fails");
}, (err) => {
// 404 is an expected failure indicated by the lack of route being set
@@ -49,15 +49,14 @@ add_test(function test_register_success() {
response.processAsync();
response.finish();
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
run_next_test();
}, err => {
do_throw("shouldn't error on a successful request");
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
do_register_cleanup(function() {

View File

@@ -26,7 +26,7 @@ add_task(function test_initialize_with_expired_urls_and_no_auth_token() {
Services.prefs.setIntPref(LOOP_URL_EXPIRY_PREF, nowSeconds - 2);
Services.prefs.clearUserPref(LOOP_FXA_TOKEN_PREF);
yield MozLoopService.initialize(mockPushHandler).then((msg) => {
yield MozLoopService.initialize().then((msg) => {
Assert.equal(msg, "registration not needed", "Initialize should not register when the " +
"URLs are expired and there are no auth tokens");
}, (error) => {
@@ -42,7 +42,7 @@ add_task(function test_initialize_with_urls_and_no_auth_token() {
response.setStatusLine(null, 200, "OK");
});
yield MozLoopService.initialize(mockPushHandler).then((msg) => {
yield MozLoopService.initialize().then((msg) => {
Assert.equal(msg, "initialized to guest status", "Initialize should register as a " +
"guest when no auth tokens but expired URLs");
}, (error) => {
@@ -66,12 +66,11 @@ add_task(function test_initialize_with_invalid_fxa_token() {
}));
});
yield MozLoopService.initialize(mockPushHandler).then(() => {
yield MozLoopService.initialize().then(() => {
Assert.ok(false, "Initializing with an invalid token should reject the promise");
},
(error) => {
let pushHandler = Cu.import("resource:///modules/loop/MozLoopService.jsm", {}).gPushHandler;
Assert.equal(pushHandler.pushUrl, kEndPointUrl, "Push URL should match");
Assert.equal(MozLoopServiceInternal.pushHandler.pushUrl, kEndPointUrl, "Push URL should match");
Assert.equal(Services.prefs.getCharPref(LOOP_FXA_TOKEN_PREF), "",
"FXA pref should be cleared if token was invalid");
Assert.equal(Services.prefs.getCharPref(LOOP_FXA_PROFILE_PREF), "",
@@ -86,7 +85,7 @@ add_task(function test_initialize_with_fxa_token() {
response.setStatusLine(null, 200, "OK");
});
yield MozLoopService.initialize(mockPushHandler).then(() => {
yield MozLoopService.initialize().then(() => {
Assert.equal(Services.prefs.getCharPref(LOOP_FXA_TOKEN_PREF), FAKE_FXA_TOKEN_DATA,
"FXA pref should still be set after initialization");
Assert.equal(Services.prefs.getCharPref(LOOP_FXA_PROFILE_PREF), FAKE_FXA_PROFILE,
@@ -98,9 +97,11 @@ function run_test() {
setupFakeLoopServer();
// Note, this is just used to speed up the test.
Services.prefs.setIntPref(LOOP_INITIAL_DELAY_PREF, 0);
MozLoopServiceInternal.mocks.pushHandler = mockPushHandler;
mockPushHandler.pushUrl = kEndPointUrl;
do_register_cleanup(function() {
MozLoopServiceInternal.mocks.pushHandler = undefined;
Services.prefs.clearUserPref(LOOP_INITIAL_DELAY_PREF);
Services.prefs.clearUserPref(LOOP_FXA_TOKEN_PREF);
Services.prefs.clearUserPref(LOOP_FXA_PROFILE_PREF);

View File

@@ -31,7 +31,7 @@ add_test(function test_registration_invalid_token() {
response.finish();
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
// Due to the way the time stamp checking code works in hawkclient, we expect a couple
// of authorization requests before we reset the token.
Assert.equal(authorizationAttempts, 2);
@@ -43,8 +43,7 @@ add_test(function test_registration_invalid_token() {
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
do_register_cleanup(function() {

View File

@@ -16,7 +16,7 @@ add_test(function test_registration_returns_hawk_session_token() {
response.finish();
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
var hawkSessionPref;
try {
hawkSessionPref = Services.prefs.getCharPref("loop.hawk-session-token");
@@ -31,8 +31,7 @@ add_test(function test_registration_returns_hawk_session_token() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
do_register_cleanup(function() {

View File

@@ -24,7 +24,7 @@ add_test(function test_registration_uses_hawk_session_token() {
response.finish();
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
run_next_test();
}, err => {
do_throw("shouldn't error on a succesful request");
@@ -32,8 +32,7 @@ add_test(function test_registration_uses_hawk_session_token() {
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
do_register_cleanup(function() {

View File

@@ -16,7 +16,7 @@ add_test(function test_registration_handles_bogus_hawk_token() {
response.finish();
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
do_throw("should not succeed with a bogus token");
}, err => {
@@ -36,8 +36,7 @@ add_test(function test_registration_handles_bogus_hawk_token() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
do_register_cleanup(function() {
@@ -45,5 +44,4 @@ function run_test()
});
run_next_test();
}

View File

@@ -83,7 +83,7 @@ add_test(function test_getAllRooms() {
returnRoomDetails(response, "Third Room Name");
});
MozLoopService.register(mockPushHandler).then(() => {
MozLoopService.register().then(() => {
LoopRooms.getAll((error, rooms) => {
do_check_false(error);
@@ -113,8 +113,7 @@ add_test(function test_getAllRooms() {
});
});
function run_test()
{
function run_test() {
setupFakeLoopServer();
mockPushHandler.registrationPushURL = kEndPointUrl;