Bug 1137843 - Loop client should not try to leave room that it fails to join. r=dmose

This commit is contained in:
Mark Banner 2015-03-24 08:46:06 +00:00
parent 422b818b0c
commit 57615e4011
3 changed files with 92 additions and 25 deletions

View File

@ -361,7 +361,9 @@ loop.shared.actions = (function() {
* XXX: should move to some roomActions module - refs bug 1079284
*/
RoomFailure: Action.define("roomFailure", {
error: Object
error: Object,
// True when the failures occurs in the join room request to the loop-server.
failedJoinRequest: Boolean
}),
/**

View File

@ -105,7 +105,7 @@ loop.store.ActiveRoomStore = (function() {
});
this._leaveRoom(actionData.error.errno === REST_ERRNOS.ROOM_FULL ?
ROOM_STATES.FULL : ROOM_STATES.FAILED);
ROOM_STATES.FULL : ROOM_STATES.FAILED, actionData.failedJoinRequest);
},
/**
@ -161,7 +161,10 @@ loop.store.ActiveRoomStore = (function() {
this._mozLoop.rooms.get(actionData.roomToken,
function(error, roomData) {
if (error) {
this.dispatchAction(new sharedActions.RoomFailure({error: error}));
this.dispatchAction(new sharedActions.RoomFailure({
error: error,
failedJoinRequest: false
}));
return;
}
@ -293,7 +296,15 @@ loop.store.ActiveRoomStore = (function() {
this._mozLoop.rooms.join(this._storeState.roomToken,
function(error, responseData) {
if (error) {
this.dispatchAction(new sharedActions.RoomFailure({error: error}));
this.dispatchAction(new sharedActions.RoomFailure({
error: error,
// This is an explicit flag to avoid the leave happening if join
// fails. We can't track it on ROOM_STATES.JOINING as the user
// might choose to leave the room whilst the XHR is in progress
// which would then mean we'd run the race condition of not
// notifying the server of a leave.
failedJoinRequest: true
}));
return;
}
@ -555,7 +566,10 @@ loop.store.ActiveRoomStore = (function() {
this._storeState.sessionToken,
function(error, responseData) {
if (error) {
this.dispatchAction(new sharedActions.RoomFailure({error: error}));
this.dispatchAction(new sharedActions.RoomFailure({
error: error,
failedJoinRequest: false
}));
return;
}
@ -567,9 +581,12 @@ loop.store.ActiveRoomStore = (function() {
* Handles leaving a room. Clears any membership timeouts, then
* signals to the server the leave of the room.
*
* @param {ROOM_STATES} nextState The next state to switch to.
* @param {ROOM_STATES} nextState The next state to switch to.
* @param {Boolean} failedJoinRequest Optional. Set to true if the join
* request to loop-server failed. It
* will skip the leave message.
*/
_leaveRoom: function(nextState) {
_leaveRoom: function(nextState, failedJoinRequest) {
if (loop.standaloneMedia) {
loop.standaloneMedia.multiplexGum.reset();
}
@ -592,10 +609,11 @@ loop.store.ActiveRoomStore = (function() {
delete this._timeout;
}
if (this._storeState.roomState === ROOM_STATES.JOINING ||
this._storeState.roomState === ROOM_STATES.JOINED ||
this._storeState.roomState === ROOM_STATES.SESSION_CONNECTED ||
this._storeState.roomState === ROOM_STATES.HAS_PARTICIPANTS) {
if (!failedJoinRequest &&
(this._storeState.roomState === ROOM_STATES.JOINING ||
this._storeState.roomState === ROOM_STATES.JOINED ||
this._storeState.roomState === ROOM_STATES.SESSION_CONNECTED ||
this._storeState.roomState === ROOM_STATES.HAS_PARTICIPANTS)) {
this._mozLoop.rooms.leave(this._storeState.roomToken,
this._storeState.sessionToken);
}

View File

@ -95,7 +95,10 @@ describe("loop.store.ActiveRoomStore", function () {
});
it("should log the error", function() {
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(console.error);
sinon.assert.calledWith(console.error,
@ -105,13 +108,19 @@ describe("loop.store.ActiveRoomStore", function () {
it("should set the state to `FULL` on server error room full", function() {
fakeError.errno = REST_ERRNOS.ROOM_FULL;
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
expect(store._storeState.roomState).eql(ROOM_STATES.FULL);
});
it("should set the state to `FAILED` on generic error", function() {
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
expect(store._storeState.failureReason).eql(FAILURE_DETAILS.UNKNOWN);
@ -121,7 +130,10 @@ describe("loop.store.ActiveRoomStore", function () {
"invalid token", function() {
fakeError.errno = REST_ERRNOS.INVALID_TOKEN;
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
expect(store._storeState.failureReason).eql(FAILURE_DETAILS.EXPIRED_OR_INVALID);
@ -131,14 +143,20 @@ describe("loop.store.ActiveRoomStore", function () {
"expired", function() {
fakeError.errno = REST_ERRNOS.EXPIRED;
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
expect(store._storeState.roomState).eql(ROOM_STATES.FAILED);
expect(store._storeState.failureReason).eql(FAILURE_DETAILS.EXPIRED_OR_INVALID);
});
it("should reset the multiplexGum", function() {
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(fakeMultiplexGum.reset);
});
@ -146,14 +164,20 @@ describe("loop.store.ActiveRoomStore", function () {
it("should set screen sharing inactive", function() {
store.setStoreState({windowId: "1234"});
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(fakeMozLoop.setScreenShareState);
sinon.assert.calledWithExactly(fakeMozLoop.setScreenShareState, "1234", false);
});
it("should disconnect from the servers via the sdk", function() {
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(fakeSdkDriver.disconnectSession);
});
@ -162,7 +186,10 @@ describe("loop.store.ActiveRoomStore", function () {
sandbox.stub(window, "clearTimeout");
store._timeout = {};
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(clearTimeout);
});
@ -174,18 +201,33 @@ describe("loop.store.ActiveRoomStore", function () {
}));
// Now simulate room failure.
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(fakeMozLoop.removeBrowserSharingListener);
});
it("should call mozLoop.rooms.leave", function() {
store.roomFailure({error: fakeError});
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: false
}));
sinon.assert.calledOnce(fakeMozLoop.rooms.leave);
sinon.assert.calledWithExactly(fakeMozLoop.rooms.leave,
"fakeToken", "1627384950");
});
it("should not call mozLoop.rooms.leave if failedJoinRequest is true", function() {
store.roomFailure(new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: true
}));
sinon.assert.notCalled(fakeMozLoop.rooms.leave);
});
});
describe("#setupWindowData", function() {
@ -271,7 +313,8 @@ describe("loop.store.ActiveRoomStore", function () {
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWithExactly(dispatcher.dispatch,
new sharedActions.RoomFailure({
error: fakeError
error: fakeError,
failedJoinRequest: false
}));
});
});
@ -449,7 +492,10 @@ describe("loop.store.ActiveRoomStore", function () {
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch,
new sharedActions.RoomFailure({error: fakeError}));
new sharedActions.RoomFailure({
error: fakeError,
failedJoinRequest: true
}));
});
});
@ -582,7 +628,8 @@ describe("loop.store.ActiveRoomStore", function () {
sinon.assert.calledOnce(dispatcher.dispatch);
sinon.assert.calledWith(dispatcher.dispatch,
new sharedActions.RoomFailure({
error: fakeError
error: fakeError,
failedJoinRequest: false
}));
});
});