Bug 1119765 - Joining and Leaving a Loop room quickly can leave the room as full. Ensure we send the leave notification if we've already sent the join. r=mikedeboer
authorMark Banner <standard8@mozilla.com>
Tue, 13 Jan 2015 15:16:49 +0000
changeset 223662 2d99ceafd75976a871b25a46a5ee838594a8a069
parent 223661 6074db81bd9e63ae77958837d585ca923c612100
child 223663 c1f04c06ad54d0ed6a67d36736a28c942125ae5c
push id28100
push userkwierso@gmail.com
push dateWed, 14 Jan 2015 01:44:55 +0000
treeherdermozilla-central@63006936ab99 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmikedeboer
bugs1119765
milestone38.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 1119765 - Joining and Leaving a Loop room quickly can leave the room as full. Ensure we send the leave notification if we've already sent the join. r=mikedeboer
browser/components/loop/content/shared/js/activeRoomStore.js
browser/components/loop/content/shared/js/roomStates.js
browser/components/loop/standalone/content/js/standaloneRoomViews.js
browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
browser/components/loop/test/shared/activeRoomStore_test.js
--- a/browser/components/loop/content/shared/js/activeRoomStore.js
+++ b/browser/components/loop/content/shared/js/activeRoomStore.js
@@ -274,16 +274,18 @@ loop.store.ActiveRoomStore = (function()
       this.setStoreState({roomState: ROOM_STATES.MEDIA_WAIT});
     },
 
     /**
      * Handles the action that signifies when media permission has been
      * granted and starts joining the room.
      */
     gotMediaPermission: function() {
+      this.setStoreState({roomState: ROOM_STATES.JOINING});
+
       this._mozLoop.rooms.join(this._storeState.roomToken,
         function(error, responseData) {
           if (error) {
             this.dispatchAction(new sharedActions.RoomFailure({error: error}));
             return;
           }
 
           this.dispatchAction(new sharedActions.JoinedRoom({
@@ -456,17 +458,18 @@ loop.store.ActiveRoomStore = (function()
 
       this._sdkDriver.disconnectSession();
 
       if (this._timeout) {
         clearTimeout(this._timeout);
         delete this._timeout;
       }
 
-      if (this._storeState.roomState === ROOM_STATES.JOINED ||
+      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) {
         this._mozLoop.rooms.leave(this._storeState.roomToken,
           this._storeState.sessionToken);
       }
 
       this.setStoreState({roomState: nextState || ROOM_STATES.ENDED});
     },
--- a/browser/components/loop/content/shared/js/roomStates.js
+++ b/browser/components/loop/content/shared/js/roomStates.js
@@ -11,16 +11,18 @@ loop.store.ROOM_STATES = {
     // The initial state of the room
     INIT: "room-init",
     // The store is gathering the room data
     GATHER: "room-gather",
     // The store has got the room data
     READY: "room-ready",
     // Obtaining media from the user
     MEDIA_WAIT: "room-media-wait",
+    // Joining the room is taking place
+    JOINING: "room-joining",
     // The room is known to be joined on the loop-server
     JOINED: "room-joined",
     // The room is connected to the sdk server.
     SESSION_CONNECTED: "room-session-connected",
     // There are participants in the room.
     HAS_PARTICIPANTS: "room-has-participants",
     // There was an issue with the room
     FAILED: "room-failed",
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -89,16 +89,17 @@ loop.standaloneRoomViews = (function(moz
           return (
             React.createElement("div", {className: "room-inner-info-area"}, 
               React.createElement("p", {className: "prompt-media-message"}, 
                 msg
               )
             )
           );
         }
+        case ROOM_STATES.JOINING:
         case ROOM_STATES.JOINED:
         case ROOM_STATES.SESSION_CONNECTED: {
           return (
             React.createElement("div", {className: "room-inner-info-area"}, 
               React.createElement("p", {className: "empty-room-message"}, 
                 mozL10n.get("rooms_only_occupant_label")
               )
             )
@@ -289,17 +290,17 @@ loop.standaloneRoomViews = (function(moz
       document.body.classList.add("is-standalone-room");
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.activeRoomStore);
     },
 
     /**
-     * Watches for when we transition to JOINED room state, so we can request
+     * Watches for when we transition to MEDIA_WAIT room state, so we can request
      * user media access.
      *
      * @param  {Object} nextProps (Unused)
      * @param  {Object} nextState Next state object.
      */
     componentWillUpdate: function(nextProps, nextState) {
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
           nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -89,16 +89,17 @@ loop.standaloneRoomViews = (function(moz
           return (
             <div className="room-inner-info-area">
               <p className="prompt-media-message">
                 {msg}
               </p>
             </div>
           );
         }
+        case ROOM_STATES.JOINING:
         case ROOM_STATES.JOINED:
         case ROOM_STATES.SESSION_CONNECTED: {
           return (
             <div className="room-inner-info-area">
               <p className="empty-room-message">
                 {mozL10n.get("rooms_only_occupant_label")}
               </p>
             </div>
@@ -289,17 +290,17 @@ loop.standaloneRoomViews = (function(moz
       document.body.classList.add("is-standalone-room");
     },
 
     componentWillUnmount: function() {
       this.stopListening(this.props.activeRoomStore);
     },
 
     /**
-     * Watches for when we transition to JOINED room state, so we can request
+     * Watches for when we transition to MEDIA_WAIT room state, so we can request
      * user media access.
      *
      * @param  {Object} nextProps (Unused)
      * @param  {Object} nextState Next state object.
      */
     componentWillUpdate: function(nextProps, nextState) {
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
           nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
--- a/browser/components/loop/test/shared/activeRoomStore_test.js
+++ b/browser/components/loop/test/shared/activeRoomStore_test.js
@@ -350,16 +350,22 @@ describe("loop.store.ActiveRoomStore", f
     });
   });
 
   describe("#gotMediaPermission", function() {
     beforeEach(function() {
       store.setStoreState({roomToken: "tokenFake"});
     });
 
+    it("should set the room state to JOINING", function() {
+      store.gotMediaPermission();
+
+      expect(store.getStoreState().roomState).eql(ROOM_STATES.JOINING);
+    });
+
     it("should call rooms.join on mozLoop", function() {
       store.gotMediaPermission();
 
       sinon.assert.calledOnce(fakeMozLoop.rooms.join);
       sinon.assert.calledWith(fakeMozLoop.rooms.join, "tokenFake");
     });
 
     it("should dispatch `JoinedRoom` on success", function() {
@@ -672,16 +678,27 @@ describe("loop.store.ActiveRoomStore", f
     it("should call mozLoop.rooms.leave", function() {
       store.windowUnload();
 
       sinon.assert.calledOnce(fakeMozLoop.rooms.leave);
       sinon.assert.calledWithExactly(fakeMozLoop.rooms.leave,
         "fakeToken", "1627384950");
     });
 
+    it("should call mozLoop.rooms.leave if the room state is JOINING",
+      function() {
+        store.setStoreState({roomState: ROOM_STATES.JOINING});
+
+        store.windowUnload();
+
+        sinon.assert.calledOnce(fakeMozLoop.rooms.leave);
+        sinon.assert.calledWithExactly(fakeMozLoop.rooms.leave,
+          "fakeToken", "1627384950");
+      });
+
     it("should set the state to CLOSING", function() {
       store.windowUnload();
 
       expect(store._storeState.roomState).eql(ROOM_STATES.CLOSING);
     });
   });
 
   describe("#leaveRoom", function() {