Bug 1074823 - Infinite ringing if the caller cancels the call in the 'connecting' state. Handle the initial state returned from the websocket. r=dmose
authorMark Banner <standard8@mozilla.com>
Tue, 30 Sep 2014 23:06:34 +0100
changeset 218121 e207db7a9a5ab4bdf02881b6802450a8c688af9e
parent 218120 fc8fca136da3fe32c29ea71da79580f3d5f940b8
child 218122 192205ae85e430ac5498fcdd16b389e828e2c58a
push id2
push usergszorc@mozilla.com
push dateWed, 12 Nov 2014 19:43:22 +0000
treeherderfig@7a5f4d72e05d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdmose
bugs1074823
milestone34.0a2
Bug 1074823 - Infinite ringing if the caller cancels the call in the 'connecting' state. Handle the initial state returned from the websocket. r=dmose
browser/components/loop/content/js/conversation.js
browser/components/loop/content/js/conversation.jsx
browser/components/loop/content/shared/js/websocket.js
browser/components/loop/test/desktop-local/conversation_test.js
browser/components/loop/test/shared/websocket_test.js
--- a/browser/components/loop/content/js/conversation.js
+++ b/browser/components/loop/content/js/conversation.js
@@ -361,18 +361,20 @@ loop.conversation = (function(mozL10n) {
      * call view if appropriate.
      */
     _setupWebSocket: function() {
       this._websocket = new loop.CallConnectionWebSocket({
         url: this.props.conversation.get("progressURL"),
         websocketToken: this.props.conversation.get("websocketToken"),
         callId: this.props.conversation.get("callId"),
       });
-      this._websocket.promiseConnect().then(function() {
-        this.setState({callStatus: "incoming"});
+      this._websocket.promiseConnect().then(function(progressStatus) {
+        this.setState({
+          callStatus: progressStatus === "terminated" ? "close" : "incoming"
+        });
       }.bind(this), function() {
         this._handleSessionError();
         return;
       }.bind(this));
 
       this._websocket.on("progress", this._handleWebSocketProgress, this);
     },
 
--- a/browser/components/loop/content/js/conversation.jsx
+++ b/browser/components/loop/content/js/conversation.jsx
@@ -361,18 +361,20 @@ loop.conversation = (function(mozL10n) {
      * call view if appropriate.
      */
     _setupWebSocket: function() {
       this._websocket = new loop.CallConnectionWebSocket({
         url: this.props.conversation.get("progressURL"),
         websocketToken: this.props.conversation.get("websocketToken"),
         callId: this.props.conversation.get("callId"),
       });
-      this._websocket.promiseConnect().then(function() {
-        this.setState({callStatus: "incoming"});
+      this._websocket.promiseConnect().then(function(progressStatus) {
+        this.setState({
+          callStatus: progressStatus === "terminated" ? "close" : "incoming"
+        });
       }.bind(this), function() {
         this._handleSessionError();
         return;
       }.bind(this));
 
       this._websocket.on("progress", this._handleWebSocketProgress, this);
     },
 
--- a/browser/components/loop/content/shared/js/websocket.js
+++ b/browser/components/loop/content/shared/js/websocket.js
@@ -94,20 +94,23 @@ loop.CallConnectionWebSocket = (function
       clearTimeout(this.connectDetails.timeout);
       delete this.connectDetails;
     },
 
     /**
      * Internal function called to resolve the connection promise.
      *
      * It will log an error if no promise is found.
+     *
+     * @param {String} progressState The current state of progress of the
+     *                               websocket.
      */
-    _completeConnection: function() {
+    _completeConnection: function(progressState) {
       if (this.connectDetails && this.connectDetails.resolve) {
-        this.connectDetails.resolve();
+        this.connectDetails.resolve(progressState);
         this._clearConnectionFlags();
         return;
       }
 
       console.error("Failed to complete connection promise - no promise available");
     },
 
     /**
@@ -222,17 +225,17 @@ loop.CallConnectionWebSocket = (function
 
       this._log("WS Receiving", event.data);
 
       var previousState = this._lastServerState;
       this._lastServerState = msg.state;
 
       switch(msg.messageType) {
         case "hello":
-          this._completeConnection();
+          this._completeConnection(msg.state);
           break;
         case "progress":
           this.trigger("progress:" + msg.state);
           this.trigger("progress", msg, previousState);
           break;
       }
     },
 
--- a/browser/components/loop/test/desktop-local/conversation_test.js
+++ b/browser/components/loop/test/desktop-local/conversation_test.js
@@ -290,24 +290,35 @@ describe("loop.conversation", function()
               rejectWebSocketConnect = reject;
             });
 
             sandbox.stub(loop.CallConnectionWebSocket.prototype, "promiseConnect").returns(promise);
           });
 
           it("should set the state to incoming on success", function(done) {
             icView = mountTestComponent();
-            resolveWebSocketConnect();
+            resolveWebSocketConnect("incoming");
 
             promise.then(function () {
               expect(icView.state.callStatus).eql("incoming");
               done();
             });
           });
 
+          it("should set the state to close on success if the progress " +
+            "state is terminated", function(done) {
+              icView = mountTestComponent();
+              resolveWebSocketConnect("terminated");
+
+              promise.then(function () {
+                expect(icView.state.callStatus).eql("close");
+                done();
+              });
+            });
+
           it("should display an error if the websocket failed to connect", function(done) {
             sandbox.stub(notifications, "errorL10n");
 
             icView = mountTestComponent();
             rejectWebSocketConnect();
 
             promise.then(function() {
             }, function () {
--- a/browser/components/loop/test/shared/websocket_test.js
+++ b/browser/components/loop/test/shared/websocket_test.js
@@ -123,18 +123,21 @@ describe("loop.CallConnectionWebSocket",
       it("should resolve the promise when the 'hello' is received",
         function(done) {
           var promise = callWebSocket.promiseConnect();
 
           dummySocket.onmessage({
             data: '{"messageType":"hello", "state":"init"}'
           });
 
-          promise.then(function() {
+          promise.then(function(state) {
+            expect(state).eql("init");
             done();
+          }, function() {
+            done(new Error("shouldn't have rejected the promise"));
           });
         });
     });
 
     describe("#close", function() {
       it("should close the socket", function() {
         callWebSocket.promiseConnect();