Bug 1079811 - A new call won't start if the outgoing call window is opened (showing feedback or retry/cancel). r=Standard8
authorRomain Gauthier <romain.gauthier@monkeypatch.me>
Fri, 17 Oct 2014 16:11:41 +0100
changeset 210888 808971467f9f5b9feb436ad631eb26055fa645b2
parent 210887 410e7c3c6a1ee96414c6026bb93365e167115cda
child 210889 75c3e79b9c7cf81ebe5599e0fdec444fcd6e585a
push id27664
push userkwierso@gmail.com
push dateSat, 18 Oct 2014 02:38:02 +0000
treeherdermozilla-central@92c87e95915e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1079811
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1079811 - A new call won't start if the outgoing call window is opened (showing feedback or retry/cancel). r=Standard8
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.ConversationStore = (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.store.ConversationStore",
       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.store.ConversationStore",
         });
       }).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.store.ConversationStore",
       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.store.ConversationStore",
       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.store.ConversationStore",
       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.store.ConversationStore",
       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.store.ConversationStore",
     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());