Bug 1079811 - A new call won't start if the outgoing call window is opened (showing feedback or retry/cancel). r=Standard8 a=lmandel
authorRomain Gauthier <romain.gauthier@monkeypatch.me>
Fri, 17 Oct 2014 16:11:41 +0100
changeset 225737 a4e22c4da890
parent 225736 2edc9ed56fa4
child 225738 bda95894a692
push id3995
push userrjesup@wgate.com
push date2014-10-20 00:58 +0000
treeherdermozilla-beta@8c42ccaf8aa1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8, lmandel
bugs1079811
milestone34.0
Bug 1079811 - A new call won't start if the outgoing call window is opened (showing feedback or retry/cancel). r=Standard8 a=lmandel
browser/components/loop/content/shared/js/conversationStore.js
browser/components/loop/test/shared/conversationStore_test.js
--- a/browser/components/loop/content/shared/js/conversationStore.js
+++ b/browser/components/loop/content/shared/js/conversationStore.js
@@ -401,16 +401,22 @@ loop.store = (function() {
       this.sdkDriver.disconnectSession();
       if (this._websocket) {
         this.stopListening(this._websocket);
 
         // Now close the websocket.
         this._websocket.close();
         delete this._websocket;
       }
+
+      // XXX: The internal callId is different from
+      // this.get("callId"), see bug 1084228 for more info.
+      var locationHash = new loop.shared.utils.Helper().locationHash();
+      var callId = locationHash.match(/\#outgoing\/(.*)/)[1];
+      navigator.mozLoop.releaseCallData(callId);
     },
 
     /**
      * Used to handle any progressed received from the websocket. This will
      * dispatch new actions so that the data can be handled appropriately.
      */
     _handleWebSocketProgress: function(progressData) {
       var action;
--- a/browser/components/loop/test/shared/conversationStore_test.js
+++ b/browser/components/loop/test/shared/conversationStore_test.js
@@ -31,16 +31,21 @@ describe("loop.ConversationStore", funct
       name: [ "Mr Smith" ],
       email: [{
         type: "home",
         value: "fakeEmail",
         pref: true
       }]
     };
 
+    navigator.mozLoop = {
+      getLoopBoolPref: sandbox.stub(),
+      releaseCallData: sandbox.stub()
+    };
+
     dispatcher = new loop.Dispatcher();
     client = {
       setupOutgoingCall: sinon.stub(),
       requestCallUrl: sinon.stub()
     };
     sdkDriver = {
       connectSession: sinon.stub(),
       disconnectSession: sinon.stub()
@@ -115,16 +120,18 @@ describe("loop.ConversationStore", funct
         });
       }).to.Throw(/sdkDriver/);
     });
   });
 
   describe("#connectionFailure", function() {
     beforeEach(function() {
       store._websocket = fakeWebsocket;
+      sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
+        .returns("#outgoing/42");
     });
 
     it("should disconnect the session", function() {
       dispatcher.dispatch(
         new sharedActions.ConnectionFailure({reason: "fake"}));
 
       sinon.assert.calledOnce(sdkDriver.disconnectSession);
     });
@@ -140,16 +147,24 @@ describe("loop.ConversationStore", funct
       store.set({callState: CALL_STATES.ALERTING});
 
       dispatcher.dispatch(
         new sharedActions.ConnectionFailure({reason: "fake"}));
 
       expect(store.get("callState")).eql(CALL_STATES.TERMINATED);
       expect(store.get("callStateReason")).eql("fake");
     });
+
+    it("should release mozLoop callsData", function() {
+      dispatcher.dispatch(
+        new sharedActions.ConnectionFailure({reason: "fake"}));
+
+      sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
+      sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
+    });
   });
 
   describe("#connectionProgress", function() {
     describe("progress: init", function() {
       it("should change the state from 'gather' to 'connecting'", function() {
         store.set({callState: CALL_STATES.GATHER});
 
         dispatcher.dispatch(
@@ -476,16 +491,18 @@ describe("loop.ConversationStore", funct
       wsMediaFailSpy = sinon.spy();
       wsCloseSpy = sinon.spy();
 
       store._websocket = {
         mediaFail: wsMediaFailSpy,
         close: wsCloseSpy
       };
       store.set({callState: CALL_STATES.ONGOING});
+      sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
+        .returns("#outgoing/42");
     });
 
     it("should disconnect the session", function() {
       dispatcher.dispatch(new sharedActions.HangupCall());
 
       sinon.assert.calledOnce(sdkDriver.disconnectSession);
     });
 
@@ -501,29 +518,38 @@ describe("loop.ConversationStore", funct
       sinon.assert.calledOnce(wsCloseSpy);
     });
 
     it("should set the callState to finished", function() {
       dispatcher.dispatch(new sharedActions.HangupCall());
 
       expect(store.get("callState")).eql(CALL_STATES.FINISHED);
     });
+
+    it("should release mozLoop callsData", function() {
+      dispatcher.dispatch(new sharedActions.HangupCall());
+
+      sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
+      sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
+    });
   });
 
   describe("#peerHungupCall", function() {
     var wsMediaFailSpy, wsCloseSpy;
     beforeEach(function() {
       wsMediaFailSpy = sinon.spy();
       wsCloseSpy = sinon.spy();
 
       store._websocket = {
         mediaFail: wsMediaFailSpy,
         close: wsCloseSpy
       };
       store.set({callState: CALL_STATES.ONGOING});
+      sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
+        .returns("#outgoing/42");
     });
 
     it("should disconnect the session", function() {
       dispatcher.dispatch(new sharedActions.PeerHungupCall());
 
       sinon.assert.calledOnce(sdkDriver.disconnectSession);
     });
 
@@ -533,23 +559,32 @@ describe("loop.ConversationStore", funct
       sinon.assert.calledOnce(wsCloseSpy);
     });
 
     it("should set the callState to finished", function() {
       dispatcher.dispatch(new sharedActions.PeerHungupCall());
 
       expect(store.get("callState")).eql(CALL_STATES.FINISHED);
     });
+
+    it("should release mozLoop callsData", function() {
+      dispatcher.dispatch(new sharedActions.PeerHungupCall());
+
+      sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
+      sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
+    });
   });
 
   describe("#cancelCall", function() {
     beforeEach(function() {
       store._websocket = fakeWebsocket;
 
       store.set({callState: CALL_STATES.CONNECTING});
+      sandbox.stub(loop.shared.utils.Helper.prototype, "locationHash")
+        .returns("#outgoing/42");
     });
 
     it("should disconnect the session", function() {
       dispatcher.dispatch(new sharedActions.CancelCall());
 
       sinon.assert.calledOnce(sdkDriver.disconnectSession);
     });
 
@@ -574,16 +609,22 @@ describe("loop.ConversationStore", funct
     it("should set the state to close if the call has terminated already", function() {
       store.set({callState: CALL_STATES.TERMINATED});
 
       dispatcher.dispatch(new sharedActions.CancelCall());
 
       expect(store.get("callState")).eql(CALL_STATES.CLOSE);
     });
 
+    it("should release mozLoop callsData", function() {
+      dispatcher.dispatch(new sharedActions.CancelCall());
+
+      sinon.assert.calledOnce(navigator.mozLoop.releaseCallData);
+      sinon.assert.calledWithExactly(navigator.mozLoop.releaseCallData, "42");
+    });
   });
 
   describe("#retryCall", function() {
     it("should set the state to gather", function() {
       store.set({callState: CALL_STATES.TERMINATED});
 
       dispatcher.dispatch(new sharedActions.RetryCall());