Bug 1023507 - Handle SDK failures when calling connect, r=dmose, ui-r=darrin

This commit is contained in:
Andrei Oprea 2014-06-25 10:30:36 +01:00
parent 9097ccebde
commit 9039763d46
6 changed files with 116 additions and 13 deletions

View File

@ -139,7 +139,6 @@ loop.shared.models = (function() {
throw new Error("Can't start session as it's not ready");
}
this.session = this.sdk.initSession(this.get("sessionId"));
this.listenTo(this.session, "sessionConnected", this._sessionConnected);
this.listenTo(this.session, "streamCreated", this._streamCreated);
this.listenTo(this.session, "connectionDestroyed",
this._connectionDestroyed);
@ -147,7 +146,8 @@ loop.shared.models = (function() {
this._sessionDisconnected);
this.listenTo(this.session, "networkDisconnected",
this._networkDisconnected);
this.session.connect(this.get("apiKey"), this.get("sessionToken"));
this.session.connect(this.get("apiKey"), this.get("sessionToken"),
this._onConnectCompletion.bind(this));
},
/**
@ -160,14 +160,22 @@ loop.shared.models = (function() {
},
/**
* Session is created.
* Manages connection status
* triggers apropriate event for connection error/success
* http://tokbox.com/opentok/tutorials/connect-session/js/
* http://tokbox.com/opentok/tutorials/hello-world/js/
* http://tokbox.com/opentok/libraries/client/js/reference/SessionConnectEvent.html
*
* @param {SessionConnectEvent} event
* @param {error|null} error
*/
_sessionConnected: function(event) {
this.trigger("session:connected", event);
this.set("ongoing", true);
_onConnectCompletion: function(error) {
if (error) {
this.trigger("session:connection-error", error);
this.endSession();
} else {
this.trigger("session:connected");
this.set("ongoing", true);
}
},
/**

View File

@ -103,10 +103,22 @@ loop.shared.router = (function(l10n) {
this._onPeerHungup);
this.listenTo(this._conversation, "session:network-disconnected",
this._onNetworkDisconnected);
this.listenTo(this._conversation, "session:connection-error",
this._notifyError);
BaseRouter.apply(this, arguments);
},
/**
* Notify the user that the connection was not possible
* @param {{code: number, message: string}} error
*/
_notifyError: function(error) {
console.log(error);
this._notifier.errorL10n("connection_error_see_console_notification");
this.endCall();
},
/**
* Starts the call. This method should be overriden.
*/

View File

@ -13,6 +13,7 @@ use_latest_firefox.innerHTML=To use Loop, please use the latest version of <a hr
incompatible_device=Incompatible device
sorry_device_unsupported=Sorry, Loop does not currently support your device.
use_firefox_windows_mac_linux=Please open this page using the latest Firefox on Windows, Android, Mac or Linux.
connection_error_see_console_notification=Call failed; see console for details.
[fr]
call_has_ended=L'appel est terminé.

View File

@ -26,7 +26,9 @@ describe("loop.shared.models", function() {
apiKey: "apiKey"
};
fakeSession = _.extend({
connect: sandbox.spy(),
connect: function () {},
endSession: sandbox.stub(),
set: sandbox.stub(),
disconnect: sandbox.spy(),
unpublish: sandbox.spy()
}, Backbone.Events);
@ -163,12 +165,72 @@ describe("loop.shared.models", function() {
sinon.assert.calledOnce(fakeSDK.initSession);
});
describe("Session events", function() {
it("should trigger a session:connected event on sessionConnected",
function(done) {
model.once("session:connected", function(){ done(); });
it("should call connect", function() {
fakeSession.connect = sandbox.stub();
fakeSession.trigger("sessionConnected");
model.startSession();
sinon.assert.calledOnce(fakeSession.connect);
sinon.assert.calledWithExactly(fakeSession.connect,
sinon.match.string, sinon.match.string,
sinon.match.function);
});
it("should set ongoing to true when no error is called back",
function() {
fakeSession.connect = function(key, token, cb) {
cb(null);
};
sinon.stub(model, "set");
model.startSession();
sinon.assert.calledWith(model.set, "ongoing", true);
});
it("should trigger session:connected when no error is called back",
function() {
fakeSession.connect = function(key, token, cb) {
cb(null);
};
sandbox.stub(model, "trigger");
model.startSession();
sinon.assert.calledWithExactly(model.trigger, "session:connected");
});
describe("Session events", function() {
it("should trigger a fail event when an error is called back",
function() {
fakeSession.connect = function(key, token, cb) {
cb({
error: true
});
};
sinon.stub(model, "endSession");
model.startSession();
sinon.assert.calledOnce(model.endSession);
sinon.assert.calledWithExactly(model.endSession);
});
it("should trigger session:connection-error event when an error is" +
" called back", function() {
fakeSession.connect = function(key, token, cb) {
cb({
error: true
});
};
sandbox.stub(model, "trigger");
model.startSession();
sinon.assert.calledOnce(model.trigger);
sinon.assert.calledWithExactly(model.trigger,
"session:connection-error", sinon.match.object);
});
it("should trigger a session:ended event on sessionDisconnected",

View File

@ -125,6 +125,24 @@ describe("loop.shared.router", function() {
});
});
describe("session:connection-error", function() {
it("should warn the user when .connect() call fails", function() {
conversation.trigger("session:connection-error");
sinon.assert.calledOnce(notifier.errorL10n);
sinon.assert.calledWithExactly(notifier.errorL10n, sinon.match.string);
});
it("should invoke endCall()", function() {
conversation.trigger("session:connection-error");
sinon.assert.calledOnce(router.endCall);
sinon.assert.calledWithExactly(router.endCall);
});
});
it("should call startCall() once the call session is ready", function() {
conversation.trigger("session:ready");

View File

@ -28,3 +28,5 @@ close_window=Close this window
cannot_start_call_session_not_ready=Can't start call, session is not ready.
network_disconnected=The network connection terminated abruptly.
connection_error_see_console_notification=Call failed; see console for details.