Bug 1144344. r=mikedeboer

This commit is contained in:
Mark Banner 2015-03-18 12:43:56 +00:00
parent 6a35c08bac
commit 5ce4696fc6
2 changed files with 125 additions and 22 deletions

View File

@ -186,21 +186,24 @@ loop.store = loop.store || {};
break;
}
case WS_STATES.CONNECTING: {
this.sdkDriver.connectSession({
apiKey: state.apiKey,
sessionId: state.sessionId,
sessionToken: state.sessionToken
});
this.mozLoop.addConversationContext(
state.windowId,
state.sessionId,
state.callId);
this.setStoreState({callState: CALL_STATES.ONGOING});
if (state.outgoing) {
// We can start the connection right away if we're the outgoing
// call because this is the only way we know the other peer has
// accepted.
this._startCallConnection();
} else if (state.callState !== CALL_STATES.ONGOING) {
console.error("Websocket unexpectedly changed to next state whilst waiting for call acceptance.");
// Abort and close the window.
this.declineCall(new sharedActions.DeclineCall({blockCaller: false}));
}
break;
}
case WS_STATES.HALF_CONNECTED:
case WS_STATES.CONNECTED: {
this.setStoreState({callState: CALL_STATES.ONGOING});
if (this.getStoreState("callState") !== CALL_STATES.ONGOING) {
console.error("Unexpected websocket state received in wrong callState");
this.setStoreState({callState: CALL_STATES.ONGOING});
}
break;
}
default: {
@ -257,6 +260,25 @@ loop.store = loop.store || {};
}
},
/**
* Handles starting a call connection - connecting the session on the
* sdk, and setting the state appropriately.
*/
_startCallConnection: function() {
var state = this.getStoreState();
this.sdkDriver.connectSession({
apiKey: state.apiKey,
sessionId: state.sessionId,
sessionToken: state.sessionToken
});
this.mozLoop.addConversationContext(
state.windowId,
state.sessionId,
state.callId);
this.setStoreState({callState: CALL_STATES.ONGOING});
},
/**
* Accepts an incoming call.
*
@ -273,9 +295,9 @@ loop.store = loop.store || {};
videoMuted: actionData.callType === CALL_TYPES.AUDIO_ONLY
});
// Accepting the call on the websocket will bring us into the connecting
// state.
this._websocket.accept();
this._startCallConnection();
},
/**

View File

@ -16,7 +16,7 @@ describe("loop.store.ConversationStore", function () {
var sandbox, dispatcher, client, store, fakeSessionData, sdkDriver;
var contact, fakeMozLoop;
var connectPromise, resolveConnectPromise, rejectConnectPromise;
var wsCancelSpy, wsCloseSpy, wsMediaUpSpy, fakeWebsocket;
var wsCancelSpy, wsCloseSpy, wsDeclineSpy, wsMediaUpSpy, fakeWebsocket;
function checkFailures(done, f) {
try {
@ -65,11 +65,13 @@ describe("loop.store.ConversationStore", function () {
wsCancelSpy = sinon.spy();
wsCloseSpy = sinon.spy();
wsDeclineSpy = sinon.spy();
wsMediaUpSpy = sinon.spy();
fakeWebsocket = {
cancel: wsCancelSpy,
close: wsCloseSpy,
decline: wsDeclineSpy,
mediaUp: wsMediaUpSpy
};
@ -225,9 +227,12 @@ describe("loop.store.ConversationStore", function () {
});
});
describe("progress: connecting", function() {
describe("progress: connecting (outgoing calls)", function() {
beforeEach(function() {
store.setStoreState({callState: CALL_STATES.ALERTING});
store.setStoreState({
callState: CALL_STATES.ALERTING,
outgoing: true
});
});
it("should change the state to 'ongoing'", function() {
@ -262,6 +267,55 @@ describe("loop.store.ConversationStore", function () {
"28", "321456", "142536");
});
});
describe("progress: connecting (incoming calls)", function() {
beforeEach(function() {
store.setStoreState({
callState: CALL_STATES.ALERTING,
outgoing: false,
windowId: 42
});
sandbox.stub(console, "error");
store._websocket = fakeWebsocket;
});
it("should log an error", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
sinon.assert.calledOnce(console.error);
});
it("should call decline on the websocket", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
sinon.assert.calledOnce(fakeWebsocket.decline);
});
it("should close the websocket", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
sinon.assert.calledOnce(fakeWebsocket.close);
});
it("should clear the call in progress for the backend", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
sinon.assert.calledOnce(fakeMozLoop.calls.clearCallInProgress);
sinon.assert.calledWithExactly(fakeMozLoop.calls.clearCallInProgress, 42);
});
it("should set the call state to CLOSE", function() {
store.connectionProgress(
new sharedActions.ConnectionProgress({wsState: WS_STATES.CONNECTING}));
expect(store.getStoreState("callState")).eql(CALL_STATES.CLOSE);
});
});
});
describe("#setupWindowData", function() {
@ -518,16 +572,43 @@ describe("loop.store.ConversationStore", function () {
sinon.assert.calledOnce(store._websocket.accept);
});
it("should change the state to 'ongoing'", function() {
store.acceptCall(
new sharedActions.AcceptCall({callType: CALL_TYPES.AUDIO_ONLY}));
expect(store.getStoreState("callState")).eql(CALL_STATES.ONGOING);
});
it("should connect the session", function() {
store.setStoreState(fakeSessionData);
store.acceptCall(
new sharedActions.AcceptCall({callType: CALL_TYPES.AUDIO_ONLY}));
sinon.assert.calledOnce(sdkDriver.connectSession);
sinon.assert.calledWithExactly(sdkDriver.connectSession, {
apiKey: "fakeKey",
sessionId: "321456",
sessionToken: "341256"
});
});
it("should call mozLoop.addConversationContext", function() {
store.setStoreState(fakeSessionData);
store.acceptCall(
new sharedActions.AcceptCall({callType: CALL_TYPES.AUDIO_ONLY}));
sinon.assert.calledOnce(fakeMozLoop.addConversationContext);
sinon.assert.calledWithExactly(fakeMozLoop.addConversationContext,
"28", "321456", "142536");
});
});
describe("#declineCall", function() {
var fakeWebsocket;
beforeEach(function() {
fakeWebsocket = store._websocket = {
decline: sinon.stub(),
close: sinon.stub()
};
store._websocket = fakeWebsocket;
store.setStoreState({windowId: 42});
});