Bug 1214582 - Adjust how room titles are displayed/managed in Loop's UI. r=Standard8
authorManuel Casas <manuel.casasbarrado@gmail.com>
Tue, 27 Oct 2015 21:16:50 +0000
changeset 304984 839ec883c9dc555a6ca104f15ed7c2261f05714c
parent 304983 e90655d486cac165a2654d66442e2db1c08b538c
child 304985 0387c496dd41424ccae6662b49fa2636117ec0d4
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersStandard8
bugs1214582
milestone44.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 1214582 - Adjust how room titles are displayed/managed in Loop's UI. r=Standard8
browser/components/loop/content/js/panel.js
browser/components/loop/content/js/panel.jsx
browser/components/loop/content/js/roomViews.js
browser/components/loop/content/js/roomViews.jsx
browser/components/loop/content/shared/js/textChatStore.js
browser/components/loop/standalone/content/js/standaloneRoomViews.js
browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
browser/components/loop/test/desktop-local/panel_test.js
browser/components/loop/test/desktop-local/roomViews_test.js
browser/components/loop/test/standalone/standaloneRoomViews_test.js
--- a/browser/components/loop/content/js/panel.js
+++ b/browser/components/loop/content/js/panel.js
@@ -416,23 +416,27 @@ loop.panel = (function(_, mozL10n) {
     },
 
     render: function() {
       var roomClasses = React.addons.classSet({
         "room-entry": true,
         "room-active": this._isActive()
       });
 
+      var roomTitle = this.props.room.decryptedContext.roomName ||
+        this.props.room.decryptedContext.urls[0].description ||
+        this.props.room.decryptedContext.urls[0].location;
+
       return (
         React.createElement("div", {className: roomClasses, 
           onClick: this.handleClickEntry, 
           onMouseLeave: this._handleMouseOut, 
           ref: "roomEntry"}, 
           React.createElement("h2", null, 
-            this.props.room.decryptedContext.roomName
+            roomTitle
           ), 
           React.createElement(RoomEntryContextItem, {
             mozLoop: this.props.mozLoop, 
             roomUrls: this.props.room.decryptedContext.urls}), 
           React.createElement(RoomEntryContextButtons, {
             dispatcher: this.props.dispatcher, 
             eventPosY: this.state.eventPosY, 
             handleClickEntry: this.handleClickEntry, 
--- a/browser/components/loop/content/js/panel.jsx
+++ b/browser/components/loop/content/js/panel.jsx
@@ -416,23 +416,27 @@ loop.panel = (function(_, mozL10n) {
     },
 
     render: function() {
       var roomClasses = React.addons.classSet({
         "room-entry": true,
         "room-active": this._isActive()
       });
 
+      var roomTitle = this.props.room.decryptedContext.roomName ||
+        this.props.room.decryptedContext.urls[0].description ||
+        this.props.room.decryptedContext.urls[0].location;
+
       return (
         <div className={roomClasses}
           onClick={this.handleClickEntry}
           onMouseLeave={this._handleMouseOut}
           ref="roomEntry">
           <h2>
-            {this.props.room.decryptedContext.roomName}
+            {roomTitle}
           </h2>
           <RoomEntryContextItem
             mozLoop={this.props.mozLoop}
             roomUrls={this.props.room.decryptedContext.urls} />
           <RoomEntryContextButtons
             dispatcher={this.props.dispatcher}
             eventPosY={this.state.eventPosY}
             handleClickEntry={this.handleClickEntry}
--- a/browser/components/loop/content/js/roomViews.js
+++ b/browser/components/loop/content/js/roomViews.js
@@ -750,18 +750,21 @@ loop.roomViews = (function(mozL10n) {
       // Handle timestamp and window closing only when the call has terminated.
       if (prevState.roomState === ROOM_STATES.ENDED &&
           this.state.roomState === ROOM_STATES.ENDED) {
         this.props.onCallTerminated();
       }
     },
 
     render: function() {
-      if (this.state.roomName) {
-        this.setTitle(this.state.roomName);
+      if (this.state.roomName || this.state.roomContextUrls) {
+        var roomTitle = this.state.roomName ||
+                        this.state.roomContextUrls[0].description ||
+                        this.state.roomContextUrls[0].location;
+        this.setTitle(roomTitle);
       }
 
       var screenShareData = {
         state: this.state.screenSharingState || SCREEN_SHARE_STATES.INACTIVE,
         visible: true
       };
 
       var shouldRenderInvitationOverlay = this._shouldRenderInvitationOverlay();
--- a/browser/components/loop/content/js/roomViews.jsx
+++ b/browser/components/loop/content/js/roomViews.jsx
@@ -750,18 +750,21 @@ loop.roomViews = (function(mozL10n) {
       // Handle timestamp and window closing only when the call has terminated.
       if (prevState.roomState === ROOM_STATES.ENDED &&
           this.state.roomState === ROOM_STATES.ENDED) {
         this.props.onCallTerminated();
       }
     },
 
     render: function() {
-      if (this.state.roomName) {
-        this.setTitle(this.state.roomName);
+      if (this.state.roomName || this.state.roomContextUrls) {
+        var roomTitle = this.state.roomName ||
+                        this.state.roomContextUrls[0].description ||
+                        this.state.roomContextUrls[0].location;
+        this.setTitle(roomTitle);
       }
 
       var screenShareData = {
         state: this.state.screenSharingState || SCREEN_SHARE_STATES.INACTIVE,
         visible: true
       };
 
       var shouldRenderInvitationOverlay = this._shouldRenderInvitationOverlay();
--- a/browser/components/loop/content/shared/js/textChatStore.js
+++ b/browser/components/loop/content/shared/js/textChatStore.js
@@ -157,19 +157,24 @@ loop.store.TextChatStore = (function() {
      * so it can be added to the list.
      *
      * @param  {sharedActions.UpdateRoomInfo} actionData
      */
     updateRoomInfo: function(actionData) {
       // XXX When we add special messages to desktop, we'll need to not post
       // multiple changes of room name, only the first. Bug 1171940 should fix this.
       if (actionData.roomName) {
+        var roomName = actionData.roomName;
+        if (!roomName && actionData.roomContextUrls && actionData.roomContextUrls.length) {
+          roomName = actionData.roomContextUrls[0].description ||
+                     actionData.roomContextUrls[0].url;
+        }
         this._appendTextChatMessage(CHAT_MESSAGE_TYPES.SPECIAL, {
           contentType: CHAT_CONTENT_TYPES.ROOM_NAME,
-          message: actionData.roomName
+          message: roomName
         });
       }
 
       // Append the context if we have any.
       if (("roomContextUrls" in actionData) && actionData.roomContextUrls &&
           actionData.roomContextUrls.length) {
         // We only support the first url at the moment.
         var urlData = actionData.roomContextUrls[0];
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.js
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.js
@@ -97,25 +97,28 @@ loop.standaloneRoomViews = (function(moz
 
     _renderFailureText: function() {
       return (
         React.createElement("p", {className: "failure"}, mozL10n.get("rooms_already_joined"))
       );
     },
 
     render: function() {
+      var roomName = this.state.roomName ||
+                     this.state.roomContextUrls[0].description ||
+                     this.state.roomContextUrls[0].location;
       // The extra scroller div here is for providing a scroll view for shorter
       // screens, as the common.css specifies overflow:hidden for the body which
       // we need in some places.
       return (
         React.createElement("div", {className: "handle-user-agent-view-scroller"}, 
           React.createElement("div", {className: "handle-user-agent-view"}, 
             React.createElement("div", {className: "info-panel"}, 
               React.createElement("p", {className: "loop-logo-text", title: mozL10n.get("clientShortname2")}), 
-              React.createElement("p", {className: "roomName"}, this.state.roomName), 
+              React.createElement("p", {className: "roomName"}, roomName), 
               React.createElement("p", {className: "loop-logo"}), 
               
                 this.state.failureReason ?
                   this._renderFailureText() :
                   this._renderJoinButton()
               
             ), 
             React.createElement(ToSView, {dispatcher: this.props.dispatcher}), 
@@ -439,26 +442,25 @@ loop.standaloneRoomViews = (function(moz
      * user media access.
      *
      * @param  {Object} nextProps (Unused)
      * @param  {Object} nextState Next state object.
      */
     componentWillUpdate: function(nextProps, nextState) {
       if (this.state.roomState !== ROOM_STATES.READY &&
           nextState.roomState === ROOM_STATES.READY) {
-        var roomName = nextState.roomName || this.state.roomName;
+        var roomName = nextState.roomName ||
+                       this.state.roomName ||
+                       this.state.roomContextUrls[0].description ||
+                       this.state.roomContextUrls[0].location;
 
-        if (roomName) {
-          this.setTitle(mozL10n.get("standalone_title_with_room_name", {
-            roomName: roomName,
-            clientShortname: mozL10n.get("clientShortname2")
-          }));
-        } else {
-          this.setTitle(mozL10n.get("clientShortname2"));
-        }
+        this.setTitle(mozL10n.get("standalone_title_with_room_name", {
+          roomName: roomName,
+          clientShortname: mozL10n.get("clientShortname2")
+        }));
       }
 
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
           nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
         this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
           publisherConfig: this.getDefaultPublisherConfig({ publishVideo: true })
         }));
       }
--- a/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
+++ b/browser/components/loop/standalone/content/js/standaloneRoomViews.jsx
@@ -97,25 +97,28 @@ loop.standaloneRoomViews = (function(moz
 
     _renderFailureText: function() {
       return (
         <p className="failure">{mozL10n.get("rooms_already_joined")}</p>
       );
     },
 
     render: function() {
+      var roomName = this.state.roomName ||
+                     this.state.roomContextUrls[0].description ||
+                     this.state.roomContextUrls[0].location;
       // The extra scroller div here is for providing a scroll view for shorter
       // screens, as the common.css specifies overflow:hidden for the body which
       // we need in some places.
       return (
         <div className="handle-user-agent-view-scroller">
           <div className="handle-user-agent-view">
             <div className="info-panel">
               <p className="loop-logo-text" title={mozL10n.get("clientShortname2")}></p>
-              <p className="roomName">{this.state.roomName}</p>
+              <p className="roomName">{roomName}</p>
               <p className="loop-logo" />
               {
                 this.state.failureReason ?
                   this._renderFailureText() :
                   this._renderJoinButton()
               }
             </div>
             <ToSView dispatcher={this.props.dispatcher} />
@@ -439,26 +442,25 @@ loop.standaloneRoomViews = (function(moz
      * user media access.
      *
      * @param  {Object} nextProps (Unused)
      * @param  {Object} nextState Next state object.
      */
     componentWillUpdate: function(nextProps, nextState) {
       if (this.state.roomState !== ROOM_STATES.READY &&
           nextState.roomState === ROOM_STATES.READY) {
-        var roomName = nextState.roomName || this.state.roomName;
+        var roomName = nextState.roomName ||
+                       this.state.roomName ||
+                       this.state.roomContextUrls[0].description ||
+                       this.state.roomContextUrls[0].location;
 
-        if (roomName) {
-          this.setTitle(mozL10n.get("standalone_title_with_room_name", {
-            roomName: roomName,
-            clientShortname: mozL10n.get("clientShortname2")
-          }));
-        } else {
-          this.setTitle(mozL10n.get("clientShortname2"));
-        }
+        this.setTitle(mozL10n.get("standalone_title_with_room_name", {
+          roomName: roomName,
+          clientShortname: mozL10n.get("clientShortname2")
+        }));
       }
 
       if (this.state.roomState !== ROOM_STATES.MEDIA_WAIT &&
           nextState.roomState === ROOM_STATES.MEDIA_WAIT) {
         this.props.dispatcher.dispatch(new sharedActions.SetupStreamElements({
           publisherConfig: this.getDefaultPublisherConfig({ publishVideo: true })
         }));
       }
--- a/browser/components/loop/test/desktop-local/panel_test.js
+++ b/browser/components/loop/test/desktop-local/panel_test.js
@@ -738,16 +738,78 @@ describe("loop.panel", function() {
 
         roomEntry.setProps({ room: updatedRoom });
 
         expect(
           roomEntry.getDOMNode().textContent)
         .eql("New room name");
       });
     });
+
+    describe("Room name priority", function() {
+      var roomEntry;
+      beforeEach(function() {
+        roomEntry = mountRoomEntry({
+          dispatcher: dispatcher,
+          room: new loop.store.Room(roomData)
+        });
+      });
+
+      function setDecryptedContext(newDecryptedContext) {
+        return new loop.store.Room(_.extend({}, roomData, {
+          decryptedContext: newDecryptedContext,
+          ctime: new Date().getTime()
+        }));
+      }
+
+      it("should use room name by default", function() {
+        var updatedRoom = setDecryptedContext({
+          roomName: "Room name",
+          urls: [
+            {
+              description: "Website title",
+              location: "https://fakeurl.com"
+            }
+          ]
+        });
+
+        roomEntry.setProps({ room: updatedRoom });
+
+        expect(roomEntry.getDOMNode().textContent).eql("Room name");
+      });
+
+      it("should use context title when there's no room title", function() {
+        var updatedRoom = setDecryptedContext({
+          urls: [
+            {
+              description: "Website title",
+              location: "https://fakeurl.com"
+            }
+          ]
+        });
+
+        roomEntry.setProps({ room: updatedRoom });
+
+        expect(roomEntry.getDOMNode().textContent).eql("Website title");
+      });
+
+      it("should use website url when there's no room title nor website", function() {
+        var updatedRoom = setDecryptedContext({
+          urls: [
+            {
+              location: "https://fakeurl.com"
+            }
+          ]
+        });
+
+        roomEntry.setProps({ room: updatedRoom });
+
+        expect(roomEntry.getDOMNode().textContent).eql("https://fakeurl.com");
+      });
+    });
   });
 
   describe("loop.panel.RoomList", function() {
     var roomStore, dispatcher, fakeEmail, dispatch, roomData;
 
     beforeEach(function() {
       fakeEmail = "fakeEmail@example.com";
       dispatcher = new loop.Dispatcher();
--- a/browser/components/loop/test/desktop-local/roomViews_test.js
+++ b/browser/components/loop/test/desktop-local/roomViews_test.js
@@ -644,16 +644,58 @@ describe("loop.roomViews", function() {
           videoMuted: false
         });
 
         view = mountTestComponent();
 
         expect(view.getDOMNode().querySelector(".local video")).not.eql(null);
       });
 
+      describe("Room name priority", function() {
+        var roomEntry;
+        beforeEach(function() {
+          activeRoomStore.setStoreState({
+            participants: [{}],
+            roomState: ROOM_STATES.JOINED,
+            roomName: "fakeName",
+            roomContextUrls: [
+              {
+                description: "Website title",
+                location: "https://fakeurl.com"
+              }
+            ]
+          });
+        });
+
+        it("should use room name by default", function() {
+          view = mountTestComponent();
+          expect(fakeWindow.document.title).to.equal("fakeName");
+        });
+
+        it("should use context title when there's no room title", function() {
+          activeRoomStore.setStoreState({ roomName: null });
+
+          view = mountTestComponent();
+          expect(fakeWindow.document.title).to.equal("Website title");
+        });
+
+        it("should use website url when there's no room title nor website", function() {
+          activeRoomStore.setStoreState({
+            roomName: null,
+            roomContextUrls: [
+                {
+                  location: "https://fakeurl.com"
+                }
+              ]
+          });
+          view = mountTestComponent();
+          expect(fakeWindow.document.title).to.equal("https://fakeurl.com");
+        });
+      });
+
     });
 
     describe("Edit Context", function() {
       it("should show the form when the edit button is clicked", function() {
         view = mountTestComponent();
         var node = view.getDOMNode();
 
         expect(node.querySelector(".room-context")).to.eql(null);
--- a/browser/components/loop/test/standalone/standaloneRoomViews_test.js
+++ b/browser/components/loop/test/standalone/standaloneRoomViews_test.js
@@ -135,82 +135,141 @@ describe("loop.standaloneRoomViews", fun
         React.createElement(
           loop.standaloneRoomViews.StandaloneHandleUserAgentView, {
             dispatcher: dispatcher
           }));
     }
 
     it("should display a join room button if the state is not ROOM_JOINED", function() {
       activeRoomStore.setStoreState({
-        roomState: ROOM_STATES.READY
+        roomState: ROOM_STATES.READY,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var button = view.getDOMNode().querySelector(".info-panel > button");
 
       expect(button.textContent).eql("rooms_room_join_label");
     });
 
     it("should dispatch a JoinRoom action when the join room button is clicked", function() {
       activeRoomStore.setStoreState({
-        roomState: ROOM_STATES.READY
+        roomState: ROOM_STATES.READY,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var button = view.getDOMNode().querySelector(".info-panel > button");
 
       TestUtils.Simulate.click(button);
 
       sinon.assert.calledOnce(dispatcher.dispatch);
       sinon.assert.calledWithExactly(dispatcher.dispatch, new sharedActions.JoinRoom());
     });
 
     it("should display a enjoy your conversation button if the state is ROOM_JOINED", function() {
       activeRoomStore.setStoreState({
-        roomState: ROOM_STATES.JOINED
+        roomState: ROOM_STATES.JOINED,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var button = view.getDOMNode().querySelector(".info-panel > button");
 
       expect(button.textContent).eql("rooms_room_joined_own_conversation_label");
     });
 
     it("should disable the enjoy your conversation button if the state is ROOM_JOINED", function() {
       activeRoomStore.setStoreState({
-        roomState: ROOM_STATES.JOINED
+        roomState: ROOM_STATES.JOINED,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var button = view.getDOMNode().querySelector(".info-panel > button");
 
       expect(button.classList.contains("disabled")).eql(true);
     });
 
     it("should not display a join button if there is a failure reason", function() {
       activeRoomStore.setStoreState({
-        failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
+        failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var button = view.getDOMNode().querySelector(".info-panel > button");
 
       expect(button).eql(null);
     });
 
     it("should display a room already joined message if opening failed", function() {
       activeRoomStore.setStoreState({
-        failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN
+        failureReason: FAILURE_DETAILS.ROOM_ALREADY_OPEN,
+        roomName: "fakeName"
       });
 
       view = mountTestComponent();
       var text = view.getDOMNode().querySelector(".failure");
 
       expect(text.textContent).eql("rooms_already_joined");
     });
+
+    describe("Room name priority", function() {
+      it("should use room name", function() {
+        activeRoomStore.setStoreState({
+          roomState: ROOM_STATES.JOINED,
+          roomName: "fakeName"
+        });
+
+        view = mountTestComponent();
+        var text = view.getDOMNode().querySelector(".roomName");
+
+        expect(
+          text.textContent)
+        .eql("fakeName");
+      });
+
+      it("should use context title when there's no room title", function() {
+        activeRoomStore.setStoreState({
+          roomState: ROOM_STATES.JOINED,
+          roomContextUrls: [
+            {
+              description: "Website title",
+              location: "https://fakeurl.com"
+            }
+          ]
+        });
+
+        view = mountTestComponent();
+        var text = view.getDOMNode().querySelector(".roomName");
+
+        expect(
+          text.textContent)
+        .eql("Website title");
+      });
+
+      it("should use website url when there's no room title nor website", function() {
+        activeRoomStore.setStoreState({
+          roomState: ROOM_STATES.JOINED,
+          roomContextUrls: [
+            {
+              location: "https://fakeurl.com"
+            }
+          ]
+        });
+
+        view = mountTestComponent();
+        var text = view.getDOMNode().querySelector(".roomName");
+
+        expect(
+          text.textContent)
+        .eql("https://fakeurl.com");
+      });
+    });
   });
 
   describe("StandaloneRoomHeader", function() {
     function mountTestComponent() {
       return TestUtils.renderIntoDocument(
         React.createElement(
           loop.standaloneRoomViews.StandaloneOverlayWrapper, {
             dispatcher: dispatcher
@@ -236,17 +295,20 @@ describe("loop.standaloneRoomViews", fun
         dispatcher: dispatcher
       }, extraProps);
       return TestUtils.renderIntoDocument(
         React.createElement(
           loop.standaloneRoomViews.StandaloneRoomFailureView, props));
     }
 
     beforeEach(function() {
-      activeRoomStore.setStoreState({ roomState: ROOM_STATES.FAILED });
+      activeRoomStore.setStoreState({
+        roomState: ROOM_STATES.FAILED,
+        roomName: "fakeName"
+      });
     });
 
     it("should display a status error message if not reason is supplied", function() {
       view = mountTestComponent();
 
       expect(view.getDOMNode().querySelector(".failed-room-message").textContent)
         .eql("status_error");
     });
@@ -360,32 +422,27 @@ describe("loop.standaloneRoomViews", fun
 
     function expectActionDispatched() {
       sinon.assert.calledOnce(dispatch);
       sinon.assert.calledWithExactly(dispatch,
         sinon.match.instanceOf(sharedActions.SetupStreamElements));
     }
 
     describe("#componentWillUpdate", function() {
+      beforeEach(function() {
+        activeRoomStore.setStoreState({ roomName: "fakeName" });
+      });
       it("should set document.title to roomName and brand name when the READY state is dispatched", function() {
-        activeRoomStore.setStoreState({ roomName: "fakeName", roomState: ROOM_STATES.INIT });
+        activeRoomStore.setStoreState({ roomState: ROOM_STATES.INIT });
         view = mountTestComponent();
         activeRoomStore.setStoreState({ roomState: ROOM_STATES.READY });
 
         expect(fakeWindow.document.title).to.equal("fakeName — clientShortname2");
       });
 
-      it("should set document.title brand name when there is no context available", function() {
-        activeRoomStore.setStoreState({ roomState: ROOM_STATES.INIT });
-        view = mountTestComponent();
-        activeRoomStore.setStoreState({ roomState: ROOM_STATES.READY });
-
-        expect(fakeWindow.document.title).to.equal("clientShortname2");
-      });
-
       it("should dispatch a `SetupStreamElements` action when the MEDIA_WAIT state " +
         "is entered", function() {
           activeRoomStore.setStoreState({ roomState: ROOM_STATES.READY });
           view = mountTestComponent();
 
           activeRoomStore.setStoreState({ roomState: ROOM_STATES.MEDIA_WAIT });
 
           expectActionDispatched(view);
@@ -451,17 +508,17 @@ describe("loop.standaloneRoomViews", fun
         });
     });
 
     describe("#componentWillReceiveProps", function() {
       beforeEach(function() {
         view = mountTestComponent();
 
         // Pretend the user waited a little bit
-        activeRoomStore.setStoreState({ roomState: ROOM_STATES.JOINING });
+        activeRoomStore.setStoreState({ roomState: ROOM_STATES.JOINING, roomName: "fakeName" });
         clock.tick(loop.standaloneRoomViews.StandaloneRoomInfoArea.RENDER_WAITING_DELAY - 1);
       });
 
       describe("Support multiple joins", function() {
         it("should send the first `TileShown` after waiting in JOINING state",
           function() {
             clock.tick(1);
 
@@ -536,17 +593,17 @@ describe("loop.standaloneRoomViews", fun
           enabled: true
         }));
       });
     });
 
     describe("#render", function() {
       beforeEach(function() {
         view = mountTestComponent();
-        activeRoomStore.setStoreState({ roomState: ROOM_STATES.JOINING });
+        activeRoomStore.setStoreState({ roomState: ROOM_STATES.JOINING, roomName: "fakeName" });
       });
 
       describe("Empty room message", function() {
         it("should not display an message immediately in the JOINED state",
           function() {
             activeRoomStore.setStoreState({ roomState: ROOM_STATES.JOINED });
 
             expect(view.getDOMNode().querySelector(".empty-room-message"))
@@ -971,16 +1028,20 @@ describe("loop.standaloneRoomViews", fun
       return TestUtils.renderIntoDocument(
         React.createElement(
           loop.standaloneRoomViews.StandaloneRoomControllerView, {
         dispatcher: dispatcher,
         isFirefox: true
       }));
     }
 
+    beforeEach(function() {
+      activeRoomStore.setStoreState({ roomName: "fakeName" });
+    });
+
     it("should not display anything if it is not known if Firefox can handle the room", function() {
       activeRoomStore.setStoreState({
         userAgentHandlesRoom: undefined
       });
 
       view = mountTestComponent();
 
       expect(view.getDOMNode()).eql(null);